First public contribution.
1 // Copyright (c) 1995-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.
20 const TInt KMajorVersionNumber=1;
21 const TInt KMinorVersionNumber=0;
23 const TUint KInvalidSetFilePointer = 0xffffffff; // INVALID_SET_FILE_POINTER
25 #pragma data_seg(".data2")
27 #pragma bss_seg(".data2")
29 static TInt ReadSpeed;
30 static TInt WriteSpeed;
36 static void Panic(TPanic aPanic)
38 User::Panic(_L("LocalFSys"),aPanic);
43 // Map aDrive to a path given by environment variables
45 TBool MapDrive(TDes& aFileName, TInt aDrive)
48 TDriveName root(TDriveUnit(aDrive).Name());
50 TBuf<3> rootWithSlash(root);
51 rootWithSlash.Append('\\');
53 if (MapEmulatedFileName(path, rootWithSlash) == KErrNone)
55 aFileName=path.Left(3); // drive letter, colon and backslash
58 aFileName=root; // no trailing backslash
62 TInt MapFileName(TDes& aFileName, TInt aDrive, const TDesC& aName)
64 TFileName n(TDriveUnit(aDrive).Name());
66 return MapEmulatedFileName(aFileName,n);
69 void MapFileNameL(TDes& aFileName, TInt aDrive, const TDesC& aName)
71 User::LeaveIfError(MapFileName(aFileName,aDrive,aName));
76 Check whether a descriptor has enough space for null-terminating and append a zero terminator if it does.
77 Supposed to be used for Win32 file operations, taking C-like strings as parameters.
78 The main purpose is to avoid panics caused by descriptors overflow.
80 @param aDes descriptor to be null-terminated; a file(directory) name presumably.
81 @return cast to LPCTSTR value of the descriptor, supposed to be the unicode string
82 @leave KErrBadName if there is no room for trailing zero
84 LPCTSTR StrPtrZL(TDes16& aDes)
86 if(aDes.MaxLength() - aDes.Length() < 1)
87 User::Leave(KErrBadName); //-- no room for terminating zero
89 return (LPCTSTR)aDes.PtrZ();
95 // Converts a TTime structure to a Windows/NT filetime. Assumes that aTime is a
98 static void timeToFileTimeL(const TTime& aTime,FILETIME* f)
101 TDateTime dateTime=aTime.DateTime();
103 #pragma warning( disable : 4244 ) // conversion from 'const int' to 'unsigned short', possible loss of data
104 t.wYear=dateTime.Year();
105 t.wMonth=dateTime.Month()+1;
106 t.wDay=dateTime.Day()+1;
107 t.wDayOfWeek=(aTime.DayNoInWeek()+1)%7;
108 t.wHour=dateTime.Hour();
109 t.wMinute=dateTime.Minute();
110 t.wSecond=dateTime.Second();
111 t.wMilliseconds=dateTime.MicroSecond()/1000;
112 #pragma warning( default : 4244 ) // conversion from 'const int' to 'unsigned short', possible loss of data
113 __ASSERT_ALWAYS(SystemTimeToFileTime(&t,f)==TRUE,User::Leave(KErrArgument));
117 // Convert Windows/NT file time to TTime
118 // Assumes the NT file time is UTC
120 static void fileTimeToTime(FILETIME* f,TTime& aTime)
123 __ASSERT_ALWAYS(FileTimeToSystemTime(f,&t)==TRUE,Panic(EFileTimeToSystemTime));
124 aTime=TDateTime(t.wYear,TMonth(t.wMonth-1),t.wDay-1,t.wHour,t.wMinute,t.wSecond,t.wMilliseconds*1000);
128 // Return the size and free space on a drive.
130 static TInt GetMediaSize(TInt aDriveNumber,TInt64& aSize,TInt64& aFree)
134 MapDrive(driveName,aDriveNumber);
135 DWORD sectorsPerCluster;
136 DWORD bytesPerSector;
139 // this function should be upgraded to GetDiskFreeSpaceEx
140 BOOL b=Emulator::GetDiskFreeSpace((LPCTSTR)driveName.PtrZ(),§orsPerCluster,&bytesPerSector,&freeClusters,&sizeClusters);
142 return Emulator::LastError();
144 TInt64 bytesPerCluster=(TInt)(sectorsPerCluster*bytesPerSector);
145 aSize=TInt64((TInt)sizeClusters)*bytesPerCluster;
146 aFree=TInt64((TInt)freeClusters)*bytesPerCluster;
151 // Return the volume name and uniqueID.
153 static TInt GetVolumeId(TInt aDriveNumber,TUint& aUniqueID)
157 MapDrive(driveName,aDriveNumber);
158 DWORD uniqueID,componentLength,flags;
159 BOOL b=Emulator::GetVolumeInformation((LPCTSTR)driveName.PtrZ(),NULL,0,&uniqueID,&componentLength,&flags,NULL,0);
161 return Emulator::LastError();
167 //#########################################################################################################################
168 //## CLocalMountCB class implementation
169 //#########################################################################################################################
172 CLocalMountCB::CLocalMountCB()
176 CLocalMountCB::~CLocalMountCB()
182 // Returns ETrue if the drive == EDriveZ
184 TBool CLocalMountCB::IsRomDrive() const
186 // WINS emulated rom drive is Z:
187 return(Drive().DriveNumber()==EDriveZ);
190 //-------------------------------------------------------------------------------------------------------------------
195 @param aForceMount Flag to indicate whether mount should be forced to succeed if an error occurs
196 @leave KErrNoMemory,KErrNotReady,KErrCorrupt,KErrUnknown.
198 void CLocalMountCB::MountL(TBool /*aForceMount*/)
201 const TInt driveNum=Drive().DriveNumber();
202 User::LeaveIfError(GetMediaSize(driveNum,s,f));
205 if (driveNum==EDriveZ)
208 User::LeaveIfError(GetVolumeId(driveNum,iUniqueID));
209 SetVolumeName(HBufC::NewL(0)); // all Win32 volumes are unnamed
211 //-- assign default value, 4G-1
212 iMaxFileSizeSupported = ((TUint64)4 << 30)-1;
215 //-- find out the maximal supported file size. For this we need to query the name of the windows filesystem that is
216 //-- used for the emulated drive
217 TBuf<20> bufWinDrive;
218 MapDrive(bufWinDrive, Drive().DriveNumber());
219 ASSERT(bufWinDrive.Length() >= 3);
223 TCHAR volFSFileName[30];
228 memset(rootName, 0, sizeof(rootName));
230 wcsncpy(rootName, (const wchar_t*)bufWinDrive.Ptr(), 3); //- something like "k:\\"
232 BOOL b = GetVolumeInformation(rootName, volName, sizeof(volName)/sizeof(TCHAR), &volSerNum, &volMaxCompLen, &volFsFlags, volFSFileName, sizeof(volFSFileName)/sizeof(TCHAR));
235 if(_wcsicmp(volFSFileName, _TEXT("NTFS")) == 0)
237 iMaxFileSizeSupported = 0xFFFFFFF0000; //-- max. file size for NTFS
240 {//-- theoretically other than FAT & NTFS filesystem are possible.. Figure yourself.
247 //-------------------------------------------------------------------------------------------------------------------
249 Try remount this volume. Checks if the volume parameters remained the same as on original MountL() call, and
250 if they are, re-initialises the mount.
251 @return KErrNone if the remount was OK
252 system-wide error code otherwise
254 TInt CLocalMountCB::ReMount()
257 TInt d=Drive().DriveNumber();
259 TInt r=GetVolumeId(d,uniqueID);
260 if (r==KErrNone && uniqueID!=iUniqueID)
265 //-------------------------------------------------------------------------------------------------------------------
266 void CLocalMountCB::Dismounted()
270 //-------------------------------------------------------------------------------------------------------------------
272 // Return the volume info.
274 void CLocalMountCB::VolumeL(TVolumeInfo& aVolume) const
278 TInt driveNum=Drive().DriveNumber();
279 User::LeaveIfError(GetMediaSize(driveNum,s,f));
280 if (driveNum==EDriveZ)
286 //-------------------------------------------------------------------------------------------------------------------
288 // Set the volume label. Not supported on Win32 volumes
290 void CLocalMountCB::SetVolumeL(TDes&)
293 User::Leave(IsRomDrive() ? KErrAccessDenied : KErrNotSupported);
296 //-------------------------------------------------------------------------------------------------------------------
298 // Return the address of the file if it is in rom
300 void CLocalMountCB::IsFileInRom(const TDesC& aName,TUint8*& aFileStart)
308 if (MapFileName(n,Drive().DriveNumber(),aName)!=KErrNone)
311 DWORD access=GENERIC_READ;
312 DWORD share=FILE_SHARE_WRITE|FILE_SHARE_READ;
313 DWORD create=OPEN_EXISTING;
314 HANDLE h=Emulator::CreateFile((LPCTSTR)n.PtrZ(),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
315 if (h==INVALID_HANDLE_VALUE)
318 CLocalFileCB::RomAddress(aName, h, aFileStart);
322 //-------------------------------------------------------------------------------------------------------------------
325 @param aName full path to the directory to create. Name validity is checked by file server.
327 void CLocalMountCB::MkDirL(const TDesC& aName)
331 User::Leave(KErrAccessDenied);
333 MapFileNameL(n,Drive().DriveNumber(),aName);
334 BOOL b=Emulator::CreateDirectory(StrPtrZL(n),NULL);
338 TInt r=Emulator::LastError();
339 if (r!=KErrAlreadyExists)
345 User::Leave(KErrAlreadyExists);
347 User::Leave(KErrAccessDenied);
350 //-------------------------------------------------------------------------------------------------------------------
353 @param aName directory name
355 void CLocalMountCB::RmDirL(const TDesC& aName)
359 User::Leave(KErrAccessDenied);
362 MapFileNameL(n,Drive().DriveNumber(),aName);
363 BOOL b=Emulator::RemoveDirectory(StrPtrZL(n));
366 User::Leave(Emulator::LastError());
369 //-------------------------------------------------------------------------------------------------------------------
373 void CLocalMountCB::DeleteL(const TDesC& aName)
377 User::Leave(KErrAccessDenied);
379 //-- check entry attributes
381 EntryL(aName, entry);
382 if (entry.IsDir() || entry.IsReadOnly())
383 User::Leave(KErrAccessDenied);
386 MapFileNameL(n,Drive().DriveNumber(),aName);
387 BOOL b=Emulator::DeleteFile(StrPtrZL(n));
390 User::Leave(Emulator::LastError());
393 //-------------------------------------------------------------------------------------------------------------------
395 // Rename a file or directory.
397 void CLocalMountCB::RenameL(const TDesC& aOldName,const TDesC& aNewName)
401 User::Leave(KErrAccessDenied);
403 TRAPD(r,EntryL(aNewName,entry));
404 if (r!=KErrNone && r!=KErrNotFound)
407 MapFileNameL(old,Drive().DriveNumber(),aOldName);
409 MapFileNameL(n,Drive().DriveNumber(),aNewName);
410 BOOL b=Emulator::MoveFile(StrPtrZL(old),StrPtrZL(n));
413 User::Leave(Emulator::LastError());
416 //-------------------------------------------------------------------------------------------------------------------
417 void CLocalMountCB::ReplaceL(const TDesC& aOldName,const TDesC& aNewName)
419 // Delete aNewName if it exists and rename anOldName.
424 User::Leave(KErrAccessDenied);
426 if(FileNamesIdentical(aOldName,aNewName))
430 TRAPD(r,DeleteL(aNewName));
431 if (r!=KErrNotFound && r!=KErrNone)
434 MapFileNameL(old,Drive().DriveNumber(),aOldName);
436 MapFileNameL(n,Drive().DriveNumber(),aNewName);
437 BOOL b=Emulator::MoveFile(StrPtrZL(old),StrPtrZL(n));
439 User::Leave(Emulator::LastError());
442 //-------------------------------------------------------------------------------------------------------------------
444 // Set and get file pointer for windows files
446 static DWORD SetFilePointerL(HANDLE hFile,LONG lDistanceToMove,DWORD dwMoveMethod)
451 dwRet=SetFilePointer(hFile,lDistanceToMove,0,dwMoveMethod);
452 if (dwRet==KInvalidSetFilePointer) // INVALID_HANDLE_VALUE
453 User::Leave(Emulator::LastError());
458 //-------------------------------------------------------------------------------------------------------------------
460 // Set and get file pointer for windows files
462 static DWORD SetFilePointer64L(HANDLE hFile, LARGE_INTEGER * lpDistanceToMove, DWORD dwMoveMethod)
467 dwRet=SetFilePointer(hFile, lpDistanceToMove->LowPart, &(lpDistanceToMove->HighPart), dwMoveMethod);
469 TInt r = Emulator::LastError();
470 if ((KInvalidSetFilePointer==dwRet) && (r != NO_ERROR))
476 //-------------------------------------------------------------------------------------------------------------------
478 Read file section without opening this file on a file server side.
480 @param aName file name; all trailing dots from the name will be removed
481 @param aFilePos start read position within a file
482 @param aLength how many bytes to read; on return will be how many bytes actually read
483 @param aDes local buffer desctriptor
484 @param aMessage from file server, used to write data to the buffer in different address space.
486 @leave on media read error
488 void CLocalMountCB::ReadSectionL(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
492 MapFileNameL(n,Drive().DriveNumber(),aName);
495 HANDLE hFile=Emulator::FindFirstFile(StrPtrZL(n),&d);
496 if (hFile==INVALID_HANDLE_VALUE)
497 User::Leave(Emulator::LastError());
500 TPtrC fileName((TText*)(&d.cFileName[0]));
501 if (fileName!=_L(".") && fileName!=_L(".."))
503 if (!Emulator::FindNextFile(hFile,&d))
505 TInt r = Emulator::LastError();
506 User::Leave(r == KErrEof ? KErrNotFound : r);
512 hFile=Emulator::CreateFile(StrPtrZL(n),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
513 if (hFile==INVALID_HANDLE_VALUE)
516 DWORD dwSizeLow, dwSizeHigh;
517 dwSizeLow=GetFileSize(hFile,&dwSizeHigh);
518 TInt r = Emulator::LastError();
519 if((NO_ERROR != r) && (INVALID_FILE_SIZE == dwSizeLow))
522 // ReadSectionL can support only upto 2G as aPos is TInt!
523 const TInt64 fileSize = MAKE_TINT64(dwSizeHigh, dwSizeHigh);
524 if(fileSize > KMaxTInt)
526 if (!CloseHandle(hFile))
527 User::Leave(Emulator::LastError());
529 User::Leave(KErrTooBig);
532 // Check that reading from aPos for aLength lies within the file
533 // if aPos is within the file, and aLength is too long, read up to EOF
534 // If aPos is beyond the file, return a zero length descriptor
536 if ((TInt)dwSizeLow>=(aPos+aLength)) // Can read entire length requested from aPos
537 SetFilePointerL(hFile,aPos,FILE_BEGIN);
539 else if ((TInt)dwSizeLow>aPos) // Can read from aPos but not entire length requested
541 SetFilePointerL(hFile,aPos,FILE_BEGIN);
542 aLength=dwSizeLow-aPos;
544 else // Cannot read from aPos because it lies outside file
545 { // Close file and leave with KErrEof
546 if (!CloseHandle(hFile))
547 User::Leave(Emulator::LastError());
549 User::Leave(KErrEof);
555 if (aMessage.Handle() == KLocalMessageHandle)
556 ((TPtr8* )aTrg)->SetLength(0);
560 TInt readTotal=Min(aLength,buf.MaxLength());
562 BOOL b=ReadFile(hFile,(TAny*)buf.Ptr(),readTotal,&ret,NULL);
563 if (!b || ((TInt)ret!=readTotal))
564 User::Leave(Emulator::LastError());
567 if(aMessage.Handle() == KLocalMessageHandle)
568 ((TPtr8* )aTrg)->Append(buf);
570 aMessage.WriteL(0,buf,pos);
573 if (((TInt)ret)<readTotal)
578 if (!CloseHandle(hFile))
579 User::Leave(Emulator::LastError());
583 //-------------------------------------------------------------------------------------------------------------------
585 // Read the entry uid if present
587 void CLocalMountCB::ReadUidL(const TDesC& aName,TEntry& anEntry) const
590 // First check to see if the first sixteen bytes form a valid UID
591 TBuf<KMaxFileName + 1> fileName=aName;
592 HANDLE hFile=Emulator::CreateFile(StrPtrZL(fileName),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
593 if (hFile==INVALID_HANDLE_VALUE)
596 TBuf8<sizeof(TCheckedUid)> checkedUidBuf;
597 checkedUidBuf.SetLength(sizeof(TCheckedUid));
598 ReadFile(hFile,&checkedUidBuf[0],sizeof(TCheckedUid),&ret,NULL);
599 if (ret!=sizeof(TCheckedUid))
602 TCheckedUid checkedUid(checkedUidBuf);
603 if(checkedUid.UidType()!=TUidType(TUid::Null(),TUid::Null(),TUid::Null()))
605 anEntry.iType=checkedUid.UidType();
610 //Look at PE file for UID section
612 const TInt KPeHeaderAddrAddr=0x3c;
613 const TInt KPeHeaderAddrSize=0x01;
614 const TInt KNumberOfSectionsOffset=0x06;
615 const TInt KNumberOfSectionsSize=0x02;
616 const TInt KSectionTableOffset=0xf8;
617 const TInt KSectionHeaderSize=0x28;
618 const TInt KSectionNameLength=0x08;
619 const TInt KPtrToRawDataOffset=0x14;
620 const TInt KPtrToRawDataSize=0x04;
621 const TText8 peText[4]={'P','E',0,0};
622 const TText8 uidText[8]={'.','S','Y','M','B','I','A','N'};
624 //Read address of start of PE header
625 if (SetFilePointer(hFile,KPeHeaderAddrAddr,0,FILE_BEGIN)==KInvalidSetFilePointer)
628 ReadFile(hFile,&peAddr,KPeHeaderAddrSize,&ret,NULL);
629 if (ret!=KPeHeaderAddrSize)
632 //Check it really is the start of PE header
633 if (SetFilePointer(hFile,peAddr,0,FILE_BEGIN)==KInvalidSetFilePointer)
636 ReadFile(hFile,text,4,&ret,NULL);
637 if (*(TInt32*)text!=*(TInt32*)peText)
640 //Read number of sections
641 if (SetFilePointer(hFile,peAddr+KNumberOfSectionsOffset,0,FILE_BEGIN)==KInvalidSetFilePointer)
644 ReadFile(hFile,§ions,KNumberOfSectionsSize,&ret,NULL);
645 if (ret!=KNumberOfSectionsSize)
648 //Go through section headers looking for UID section
649 if (SetFilePointer(hFile,peAddr+KSectionTableOffset,0,FILE_BEGIN)==KInvalidSetFilePointer)
654 TText8 name[KSectionNameLength];
655 ReadFile(hFile,name,KSectionNameLength,&ret,NULL);
656 if (ret!=KSectionNameLength)
658 if (*(TInt64*)name==*(TInt64*)uidText)
660 if (SetFilePointer(hFile,KSectionHeaderSize-KSectionNameLength,0,FILE_CURRENT)==KInvalidSetFilePointer)
667 if (SetFilePointer(hFile,KPtrToRawDataOffset-KSectionNameLength,0,FILE_CURRENT)==KInvalidSetFilePointer)
670 ReadFile(hFile,&uidOffset,KPtrToRawDataSize,&ret,NULL);
671 if (ret!=KPtrToRawDataSize)
675 if (SetFilePointer(hFile,uidOffset,0,FILE_BEGIN)==KInvalidSetFilePointer)
676 User::Leave(KErrGeneral);
678 TEmulatorImageHeader header;
679 ReadFile(hFile,&header,sizeof(header),&ret,NULL);
680 if (ret==sizeof(header))
681 anEntry.iType=*(TUidType*)&header;
685 if (!CloseHandle(hFile))
686 User::Leave(Emulator::LastError());
689 //-------------------------------------------------------------------------------------------------------------------
691 Try to find a directory entry by the given name and path.
692 This method _must_ leave if the entry is not found. See the caller.
694 @param aName path to the directory object. all trailing dots from the name will be removed.
695 @param anEntry on return will contain the entry data
697 @leave KErrPathNotFound if there is no path to the aName
698 KErrNotFound if the entry corresponding to the aName is not found
699 system-wide erorr code of media read failure.
701 void CLocalMountCB::EntryL(const TDesC& aName,TEntry& anEntry) const
705 MapFileNameL(n,Drive().DriveNumber(),aName);
707 HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&d);
708 if (h==INVALID_HANDLE_VALUE)
709 User::Leave(Emulator::LastError());
712 TPtrC fileName((TText*)(&d.cFileName[0]));
713 if (fileName!=_L(".") && fileName!=_L(".."))
715 if (!Emulator::FindNextFile(h,&d))
717 TInt r = Emulator::LastError();
718 User::Leave(r == KErrEof ? KErrNotFound : r);
722 anEntry.iName.Des()=(TText*)(&d.cFileName[0]);
723 anEntry.iAtt=d.dwFileAttributes&KEntryAttMaskSupported;
725 anEntry.iAtt|=KEntryAttReadOnly;
727 anEntry.SetFileSize(MAKE_TINT64(d.nFileSizeHigh,d.nFileSizeLow));
729 fileTimeToTime(&d.ftLastWriteTime,anEntry.iModified);
733 //-------------------------------------------------------------------------------------------------------------------
735 Set directory entry details.
736 @param aName entry name; all trailing dots from the name will be removed
737 @param aTime entry modification time (and last access as well)
738 @param aSetAttMask entry attributes OR mask
739 @param aClearAttMask entry attributes AND mask
742 void CLocalMountCB::SetEntryL(const TDesC& aName,const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
746 User::Leave(KErrAccessDenied);
748 MapFileNameL(n,Drive().DriveNumber(),aName);
749 TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
750 DWORD att=Emulator::GetFileAttributes(StrPtrZL(n));
751 if (att==0xffffffffu)
752 User::Leave(Emulator::LastError());
754 if (setAttMask|aClearAttMask)
757 att&=(~aClearAttMask);
758 if (!Emulator::SetFileAttributes((LPCTSTR)n.Ptr(),att))
759 User::Leave(Emulator::LastError());
762 if (aSetAttMask&KEntryAttModified)
765 timeToFileTimeL(aTime,&f);
767 if (att&KEntryAttReadOnly)
769 DWORD writeableAtt=att&(~KEntryAttReadOnly);
770 if (!Emulator::SetFileAttributes((LPCTSTR)n.Ptr(),writeableAtt))
771 User::Leave(Emulator::LastError());
775 if (att&KEntryAttDir)
777 h=Emulator::CreateFile((LPCTSTR)n.Ptr(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_DIRECTORY|FILE_FLAG_BACKUP_SEMANTICS, NULL);
778 if (h==INVALID_HANDLE_VALUE)
779 User::Leave(Emulator::LastError());
783 h=Emulator::CreateFile((LPCTSTR)n.Ptr(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
784 if (h==INVALID_HANDLE_VALUE)
785 User::Leave(Emulator::LastError());
788 if (!SetFileTime(h,NULL,&f,&f))
790 TInt error = Emulator::LastError();
796 User::Leave(Emulator::LastError());
798 if ((att&KEntryAttReadOnly) && !Emulator::SetFileAttributes((LPCTSTR)n.Ptr(),att))
799 User::Leave(Emulator::LastError());
803 //-------------------------------------------------------------------------------------------------------------------
805 Open/Create/Replace a file on the current mount.
807 @param aName file name; all trailing dots from the name will be removed
808 @param aMode File open mode, See TFileMode
809 @param anOpen specifies action: open, create or replace the file
810 @param aFile pointer to the CFileCB object to populate
813 void CLocalMountCB::FileOpenL(const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB* aFile)
816 if (IsRomDrive() && (anOpen!=EFileOpen || (aMode&EFileWrite)))
817 User::Leave(KErrAccessDenied);
819 MapFileNameL(n,Drive().DriveNumber(),aName);
821 DWORD access=GENERIC_READ|GENERIC_WRITE;
822 DWORD share=FILE_SHARE_WRITE|FILE_SHARE_READ;
826 case EFileOpen: create=OPEN_EXISTING; break;
827 case EFileCreate: create=CREATE_NEW; break;
828 case EFileReplace: create=CREATE_ALWAYS; break;
831 HANDLE h=Emulator::CreateFile(StrPtrZL(n),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
833 if((h==INVALID_HANDLE_VALUE) && !(aMode&EFileWrite))
835 // If windows will not allow write access and it was not requested then open for read only
837 h=Emulator::CreateFile(StrPtrZL(n),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
840 if (h==INVALID_HANDLE_VALUE)
841 User::Leave(Emulator::LastError());
842 CLocalFileCB& file=(*((CLocalFileCB*)aFile));
845 BY_HANDLE_FILE_INFORMATION info;
846 if (!GetFileInformationByHandle(h,&info))
847 User::Leave(Emulator::LastError());
849 const TUint64 fileSize = MAKE_TUINT64(info.nFileSizeHigh, info.nFileSizeLow);
851 // Check on file size
852 if(MaxFileSizeSupported() < fileSize)
853 User::Leave(KErrTooBig);
855 file.SetMaxSupportedSize(MaxFileSizeSupported());
856 file.SetSize64(fileSize, EFalse);
857 file.SetAtt(info.dwFileAttributes&KEntryAttMaskSupported);
860 // file.iAtt|=KEntryAttReadOnly;
861 TTime tempTime=file.Modified();
862 fileTimeToTime(&info.ftLastWriteTime,tempTime);
863 file.SetModified(tempTime);
866 void AppendAsteriskL(TDes& aDes)
868 if (aDes.Length()==aDes.MaxLength())
869 User::Leave(KErrBadName);
873 //-------------------------------------------------------------------------------------------------------------------
875 Open a directory on the current mount.
877 @param aName path to the object in the directory we want to open; all trailing dots from the name will be removed
878 @param aDir dir. CB to be filled in.
880 If there is no such a path, this method must leave with KErrPathNotFound
882 @leave KErrPathNotFound if thereis no such path
883 @leave error code on media read fault
885 void CLocalMountCB::DirOpenL(const TDesC& aName,CDirCB* aDir)
890 MapFileNameL(n,Drive().DriveNumber(),aName);
891 parse.Set(n,NULL,NULL);
892 n=parse.DriveAndPath();
894 WIN32_FIND_DATA info;
895 HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&info);
896 if (h==INVALID_HANDLE_VALUE)
898 TInt error=Emulator::LastError();
900 TInt r=parser.Set(n,NULL,NULL);
903 if (!parser.IsRoot() || Drive().DriveNumber()!=0 || error!=KErrNotFound)
907 CLocalDirCB& dir=(*((CLocalDirCB*)aDir));
909 dir.SetPending(ETrue);
910 dir.iEntry.iName.Des()=(TText*)(&info.cFileName[0]);
911 dir.iEntry.iAtt=info.dwFileAttributes&KEntryAttMaskSupported;
913 const TInt64 fileSize = MAKE_TINT64(info.nFileSizeHigh,info.nFileSizeLow);
914 dir.iEntry.SetFileSize(fileSize);
917 if (parse.NameAndExt().Length()==0)
920 fileTimeToTime(&info.ftLastWriteTime,dir.iEntry.iModified);
923 //-------------------------------------------------------------------------------------------------------------------
925 // Read directly from disk
927 void CLocalMountCB::RawReadL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aDes*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) const
929 User::Leave(KErrNotSupported);
932 //-------------------------------------------------------------------------------------------------------------------
934 // Write directly to disk
936 void CLocalMountCB::RawWriteL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aDes*/ ,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/)
938 User::Leave(KErrNotSupported);
941 //-------------------------------------------------------------------------------------------------------------------
943 // Get the short name associated with aLongName
945 void CLocalMountCB::GetShortNameL(const TDesC& aLongName,TDes& aShortName)
949 User::Leave(KErrNotSupported);
952 MapFileNameL(n,Drive().DriveNumber(),aLongName);
954 HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&d);
955 if (h==INVALID_HANDLE_VALUE)
956 User::Leave(Emulator::LastError());
958 if (d.cAlternateFileName[0]) // we have a dos name too
959 aShortName=(TText*)(&d.cAlternateFileName[0]);
961 aShortName=(TText*)(&d.cFileName[0]);
964 //-------------------------------------------------------------------------------------------------------------------
966 // Get the short name associated with aLongName
968 void CLocalMountCB::GetLongNameL(const TDesC& aShortName,TDes& aLongName)
972 User::Leave(KErrNotSupported);
975 MapFileNameL(n,Drive().DriveNumber(),aShortName);
977 HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&d);
978 if (h==INVALID_HANDLE_VALUE)
979 User::Leave(Emulator::LastError());
981 aLongName=(TText*)(&d.cFileName[0]);
984 //-------------------------------------------------------------------------------------------------------------------
986 Reports whether the specified interface is supported - if it is,
987 the supplied interface object is modified to it
989 @param aInterfaceId The interface of interest
990 @param aInterface The interface object
991 @return KErrNone if the interface is supported, otherwise KErrNotFound
993 @see CMountCB::GetInterface()
995 TInt CLocalMountCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
999 case EFileExtendedInterface:
1000 ((CMountCB::MFileExtendedInterface*&) aInterface) = this;
1003 case ELocalBufferSupport:
1004 // CLocalMountCB doesn't ever use any extensions?
1005 // - seems to not have any iProxyDrive or LocalDrive() or similar,
1006 // so we'll just return KErrNone here.
1010 return CMountCB::GetInterface(aInterfaceId,aInterface,aInput);
1014 //-------------------------------------------------------------------------------------------------------------------
1015 TInt CLocalMountCB::LocalBufferSupport()
1017 TAny* dummyInterface = NULL;
1018 TAny* dummyInput = NULL;
1019 return GetInterface(ELocalBufferSupport,dummyInterface,dummyInput);
1022 //-------------------------------------------------------------------------------------------------------------------
1024 Read file section without opening this file on a file server side.
1026 @param aName file name; all trailing dots from the name will be removed
1027 @param aFilePos start read position within a file
1028 @param aLength how many bytes to read; on return will be how many bytes actually read
1029 @param aDes local buffer desctriptor
1030 @param aMessage from file server, used to write data to the buffer in different address space.
1032 @leave on media read error
1034 void CLocalMountCB::ReadSection64L(const TDesC& aName, TInt64 aPos, TAny* aTrg, TInt aLength, const RMessagePtr2& aMessage)
1037 MapFileNameL(n,Drive().DriveNumber(),aName);
1040 HANDLE hFile=Emulator::FindFirstFile(StrPtrZL(n),&d);
1041 if (hFile==INVALID_HANDLE_VALUE)
1042 User::Leave(Emulator::LastError());
1046 TPtrC fileName((TText*)(&d.cFileName[0]));
1047 if (fileName!=_L(".") && fileName!=_L(".."))
1049 if (!Emulator::FindNextFile(hFile,&d))
1051 TInt r = Emulator::LastError();
1052 User::Leave(r == KErrEof ? KErrNotFound : r);
1058 hFile=Emulator::CreateFile(StrPtrZL(n),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
1059 if (hFile==INVALID_HANDLE_VALUE)
1062 DWORD dwSizeLow, dwSizeHigh;
1063 dwSizeLow=GetFileSize(hFile,&dwSizeHigh);
1064 TInt r = Emulator::LastError();
1065 if((NO_ERROR != r) && (INVALID_FILE_SIZE == dwSizeLow))
1068 // Check on file size
1069 const TInt64 fileSize = MAKE_TINT64(dwSizeHigh, dwSizeLow);
1070 if(MaxFileSizeSupported() < (TUint64)fileSize)
1072 if (!CloseHandle(hFile))
1073 User::Leave(Emulator::LastError());
1075 User::Leave(KErrTooBig);
1078 // Check that reading from aPos for aLength lies within the file
1079 // if aPos is within the file, and aLength is too long, read up to EOF
1080 // If aPos is beyond the file, return a zero length descriptor
1082 if (fileSize>=aPos+aLength) // Can read entire length requested from aPos
1083 SetFilePointer64L(hFile,(LARGE_INTEGER *)&aPos,FILE_BEGIN);
1085 else if (fileSize>aPos) // Can read from aPos but not entire length requested
1087 SetFilePointer64L(hFile,(LARGE_INTEGER *)&aPos,FILE_BEGIN);
1088 aLength=(TInt)(fileSize-aPos);
1090 else // Cannot read from aPos because it lies outside file
1091 { // Close file and leave with KErrEof
1092 if (!CloseHandle(hFile))
1093 User::Leave(Emulator::LastError());
1095 User::Leave(KErrEof);
1101 if (aMessage.Handle() == KLocalMessageHandle)
1102 ((TPtr8* )aTrg)->SetLength(0);
1106 TInt readTotal=Min(aLength,buf.MaxLength());
1108 BOOL b=ReadFile(hFile,(TAny*)buf.Ptr(),readTotal,&ret,NULL);
1109 if (!b || ((TInt)ret!=readTotal))
1110 User::Leave(Emulator::LastError());
1113 if(aMessage.Handle() == KLocalMessageHandle)
1114 ((TPtr8* )aTrg)->Append(buf);
1116 aMessage.WriteL(0,buf,pos);
1119 if (((TInt)ret)<readTotal)
1124 if (!CloseHandle(hFile))
1125 User::Leave(Emulator::LastError());
1128 //-------------------------------------------------------------------------------------------------------------------
1131 CLocalMountCB control method.
1132 @param aLevel specifies the operation to perfrom on the mount
1133 @param aOption specific option for the given operation
1134 @param aParam pointer to generic parameter, its meaning depends on aLevel and aOption
1136 @return standard error code.
1139 TInt CLocalMountCB::MountControl(TInt aLevel, TInt aOption, TAny* aParam)
1141 //-- File System - specific queries
1142 if(aLevel == EMountFsParamQuery && aOption == ESQ_GetMaxSupportedFileSize)
1143 {//-- this is a query to provide the max. supported file size; aParam is a pointer to TUint64 to return the value
1144 *(TUint64*)aParam = MaxFileSizeSupported();
1148 return KErrNotSupported;
1151 //#########################################################################################################################
1152 //## CLocalFileCB class implementation
1153 //#########################################################################################################################
1156 CLocalFileCB::CLocalFileCB()
1160 CLocalFileCB::~CLocalFileCB()
1163 if (iAtt&KEntryAttModified)
1165 TRAPD(ret,FlushDataL());
1166 // if (ret!=KErrNone) // Can fail if floppy disk is removed
1167 // Panic(EFileClose); // Ignore error
1169 if (iWinHandle!=NULL && !CloseHandle(iWinHandle))
1173 //-------------------------------------------------------------------------------------------------------------------
1175 // Returns ETrue if the drive number == EDriveZ
1177 TBool CLocalFileCB::IsRomDrive() const
1180 // WINS emulated rom drive is Z:
1181 return(((CLocalFileCB*)this)->Mount().Drive().DriveNumber()==EDriveZ);
1184 //-------------------------------------------------------------------------------------------------------------------
1186 // Check that the file pointer iCurrentPos is positioned correctly
1187 // in relation to the Win32 file pointer
1189 void CLocalFileCB::CheckPosL(TInt64 aPos)
1191 // Get the current Win32 file pointer position
1194 DWORD position=SetFilePointer(iWinHandle,pos.LowPart,&pos.HighPart,FILE_CURRENT);
1195 TInt r = Emulator::LastError();
1196 if ((KInvalidSetFilePointer == position) && (r != NO_ERROR))
1198 // Set iCurrentPos and Win32 file pointers to aPos if they are different to each
1199 // other or different to aPos
1200 if ((pos.QuadPart!=iCurrentPos) || (iCurrentPos!=aPos))
1203 pos.QuadPart = aPos;
1204 position = SetFilePointer(iWinHandle,pos.LowPart,&pos.HighPart,FILE_BEGIN);
1205 r = Emulator::LastError();
1206 if ((KInvalidSetFilePointer == position) && (r != NO_ERROR))
1212 //-------------------------------------------------------------------------------------------------------------------
1213 void CLocalFileCB::ReadL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
1215 ReadL((TInt64)aPos, aLength, (TDes8*)aDes, aMessage, 0);
1218 //-------------------------------------------------------------------------------------------------------------------
1219 void CLocalFileCB::WriteL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
1221 WriteL((TInt64)aPos, aLength, (TDesC8*)aDes, aMessage, 0);
1229 //-------------------------------------------------------------------------------------------------------------------
1231 TInt CLocalFileCB::RomAddress(const TDesC& aName, HANDLE aFile, TUint8*& aAddr)
1233 static CArrayFixSeg<SRomMap>* gRomMap = new CArrayFixSeg<SRomMap>(64);
1234 for (TInt ii=0; ii<gRomMap->Count(); ii++)
1236 if (*gRomMap->At(ii).iName == aName)
1238 aAddr = gRomMap->At(ii).iAddr;
1243 HANDLE fileMapping=CreateFileMappingA(aFile,NULL,PAGE_READONLY,0,0,NULL);
1245 return Emulator::LastError();
1246 aAddr=(TUint8*)MapViewOfFile(fileMapping,FILE_MAP_READ,0,0,0);
1248 entry.iAddr = aAddr;
1249 entry.iName = aName.Alloc();
1252 TRAPD(ignore, gRomMap->AppendL(entry));
1257 //-------------------------------------------------------------------------------------------------------------------
1259 // If ROM file, do a memory map and return the address
1261 TInt CLocalFileCB::Address(TInt& aPos) const
1264 TBool isRomFile=IsRomDrive();
1266 return(KErrNotSupported);
1272 CLocalFileCB* This=(CLocalFileCB*)this;
1273 TInt err = RomAddress(*iFileName, iWinHandle, This->iFilePtr);
1277 aPos=(TInt)((TUint8*)iFilePtr+aPos);
1281 //-------------------------------------------------------------------------------------------------------------------
1283 // Set the file size.
1285 void CLocalFileCB::SetSizeL(TInt aSize)
1290 //-------------------------------------------------------------------------------------------------------------------
1292 // Set the entry's attributes and modified time.
1294 void CLocalFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
1298 User::Leave(KErrAccessDenied);
1299 TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
1300 if (setAttMask|aClearAttMask)
1303 iAtt&=(~aClearAttMask);
1304 iAtt|=KEntryAttModified;
1306 if (aSetAttMask&KEntryAttModified)
1308 iAtt|=KEntryAttModified;
1311 //-------------------------------------------------------------------------------------------------------------------
1313 // Commit any buffered date to the media.
1315 void CLocalFileCB::FlushAllL()
1320 //-------------------------------------------------------------------------------------------------------------------
1322 // Commit any buffered date to the media.
1324 void CLocalFileCB::FlushDataL()
1331 TInt driveNumber=Mount().Drive().DriveNumber();
1332 MapFileNameL(n,driveNumber,FileName());
1334 if(!Emulator::SetFileAttributes(StrPtrZL(n),iAtt&KEntryAttMaskSupported))
1335 User::Leave(Emulator::LastError()); // Panic(EFileCloseSetAttributes);
1337 timeToFileTimeL(iModified,&f);
1338 if (!SetFileTime(iWinHandle,&f,&f,&f))
1339 User::Leave(Emulator::LastError());
1341 iAtt&=(~KEntryAttModified);
1344 //-------------------------------------------------------------------------------------------------------------------
1346 // Rename the file while open
1348 void CLocalFileCB::RenameL(const TDesC& aNewName)
1351 TInt driveNumber=Mount().Drive().DriveNumber();
1354 MapFileNameL(n1,driveNumber,FileName());
1356 MapFileNameL(n2,driveNumber,aNewName);
1358 CloseHandle(iWinHandle);
1360 if (!Emulator::MoveFile(StrPtrZL(n1),StrPtrZL(n2)))
1362 ret=Emulator::LastError();
1365 DWORD access=GENERIC_READ|GENERIC_WRITE;
1366 DWORD share=FILE_SHARE_WRITE|FILE_SHARE_READ;
1367 DWORD create=OPEN_EXISTING;
1368 iWinHandle=Emulator::CreateFile(StrPtrZL(n2),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
1369 if (iWinHandle==INVALID_HANDLE_VALUE)
1370 User::Leave(Emulator::LastError());
1373 pos.QuadPart = iCurrentPos;
1374 DWORD position = SetFilePointer(iWinHandle,pos.LowPart,&pos.HighPart,FILE_BEGIN);
1375 TInt r = Emulator::LastError();
1376 if ((KInvalidSetFilePointer == position) && (r != NO_ERROR))
1379 User::LeaveIfError(ret);
1380 AllocBufferL(iFileName,aNewName);
1383 //-------------------------------------------------------------------------------------------------------------------
1384 TInt CLocalFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
1386 switch(aInterfaceId)
1388 case EExtendedFileInterface:
1389 ((CFileCB::MExtendedFileInterface*&) aInterface) = this;
1393 return CFileCB::GetInterface(aInterfaceId,aInterface,aInput);
1397 //-------------------------------------------------------------------------------------------------------------------
1399 Read data from the file.
1401 @param aFilePos start read position within a file
1402 @param aLength how many bytes to read; on return will be how many bytes actually read
1403 @param aDes local buffer desctriptor
1404 @param aMessage from file server, used to write data to the buffer in different address space.
1405 @param aDesOffset offset within data descriptor where the data will be copied
1407 @leave on media read error
1410 void CLocalFileCB::ReadL(TInt64 aPos,TInt& aLength,TDes8* aDes,const RMessagePtr2& aMessage, TInt aOffset)
1413 const TUint64 KMaxFilePosition = LocalMount().MaxFileSizeSupported()-1;
1416 if(KMaxFilePosition < (TUint64)aPos)
1417 User::Leave(KErrNotSupported);
1424 if (aMessage.Handle() == KLocalMessageHandle)
1425 ((TPtr8* )aDes)->SetLength(0);
1429 TInt s=Min(len,buf.MaxLength());
1431 BOOL b=ReadFile(iWinHandle,(TAny*)buf.Ptr(),s,&res,NULL);
1433 User::Leave(Emulator::LastError());
1437 if (aMessage.Handle() == KLocalMessageHandle)
1438 ((TPtr8* )aDes)->Append(buf);
1440 aMessage.WriteL(0,buf,pos + aOffset);
1447 TInt delay = (ReadSpeed * aLength) >> 10;
1449 User::AfterHighRes(delay);
1451 iCurrentPos=aPos+pos;
1454 //-------------------------------------------------------------------------------------------------------------------
1456 Write data to the file.
1458 @param aFilePos start write position within a file
1459 @param aLength how many bytes to write; on return contain amount of data actually written
1460 @param aDes local buffer desctriptor
1461 @param aMessage from file server, used to write data to the media from different address space.
1462 @param aDesOffset offset within data descriptor
1464 @leave on media read error
1467 void CLocalFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aDes,const RMessagePtr2& aMessage, TInt aOffset)
1470 User::Leave(KErrAccessDenied);
1473 const TUint64 KMaxFileSize = LocalMount().MaxFileSizeSupported();
1474 const TUint64 KMaxFilePosition = KMaxFileSize - 1;
1476 if( KMaxFilePosition < (TUint64)aPos || KMaxFileSize < (TUint64)(aPos + aLength) )
1477 User::Leave(KErrNotSupported);
1486 TInt s=Min(len,buf.MaxLength());
1488 if (aMessage.Handle() == KLocalMessageHandle)
1489 buf.Copy( ((TPtr8* )aDes)->MidTPtr(pos, s) );
1491 aMessage.ReadL(0,buf,pos + aOffset);
1494 BOOL b=WriteFile(iWinHandle,buf.Ptr(),s,&res,NULL);
1497 User::Leave(Emulator::LastError());
1500 User::Leave(KErrCorrupt);
1505 TInt delay = (WriteSpeed * aLength) >> 10;
1507 User::AfterHighRes(delay);
1509 iCurrentPos=aPos+pos;
1512 //-------------------------------------------------------------------------------------------------------------------
1515 @param aSize new file size.
1517 void CLocalFileCB::SetSizeL(TInt64 aSize)
1519 const TUint64 KMaxFileSize = LocalMount().MaxFileSizeSupported();
1521 if(KMaxFileSize < (TUint64)aSize)
1522 User::Leave(KErrNotSupported);
1525 if(!SetEndOfFile(iWinHandle))
1528 User::Leave(Emulator::LastError());
1531 SetSize64(aSize, EFalse);
1534 //#########################################################################################################################
1535 //## CLocalDirCB class implementation
1536 //#########################################################################################################################
1538 CLocalDirCB::CLocalDirCB()
1543 CLocalDirCB::~CLocalDirCB()
1546 if (iWinHandle!=NULL && !FindClose(iWinHandle))
1550 //-------------------------------------------------------------------------------------------------------------------
1551 TBool CLocalDirCB::MatchUid()
1554 if (iUidType[0]!=TUid::Null() || iUidType[1]!=TUid::Null() || iUidType[2]!=TUid::Null())
1560 //-------------------------------------------------------------------------------------------------------------------
1561 /** @return ETrue if the aUidTrg matches aUidSuitor */
1562 static TBool CompareUid(const TUidType& aUidTrg, const TUidType& aUidSuitor)
1565 if (aUidTrg[0]!=TUid::Null() && aUidTrg[0]!=aUidSuitor[0])
1567 if (aUidTrg[1]!=TUid::Null() && aUidTrg[1]!=aUidSuitor[1])
1569 if (aUidTrg[2]!=TUid::Null() && aUidTrg[2]!=aUidSuitor[2])
1574 //-------------------------------------------------------------------------------------------------------------------
1576 Read current entry from the directory and move to the next one.
1577 This function must leave KErrEof when the end of directory is reached
1579 @param anEntry extracted directory entry
1580 @leave KErrEof when there are no more entries in the directory
1581 system-wide error code on media read fault.
1584 void CLocalDirCB::ReadL(TEntry& anEntry)
1587 if (iWinHandle==NULL)
1588 User::Leave(KErrEof);
1594 WIN32_FIND_DATA info;
1595 if (!Emulator::FindNextFile(iWinHandle,&info))
1596 User::Leave(Emulator::LastError());
1598 iEntry.iName.Des()=(TText*)(&info.cFileName[0]);
1599 iEntry.iAtt=info.dwFileAttributes&KEntryAttMaskSupported;
1600 iEntry.SetFileSize(MAKE_TINT64(info.nFileSizeHigh,info.nFileSizeLow));
1601 fileTimeToTime(&info.ftLastWriteTime,iEntry.iModified);
1605 if (anEntry.iName==_L(".") || anEntry.iName==_L(".."))
1607 if ((iFullName.NameAndExt()==_L("*.*") || iFullName.NameAndExt()==_L("*") || anEntry.iName.MatchF(iFullName.NameAndExt())!=KErrNotFound) && Mount().MatchEntryAtt(anEntry.iAtt&KEntryAttMaskSupported,iAtt))
1612 TBuf<KMaxFileName> driveAndPath=iFullName.DriveAndPath();
1613 fileName.Set(anEntry.iName,&driveAndPath,NULL);
1614 (*(CLocalMountCB*)&Mount()).ReadUidL(fileName.FullName(),anEntry);
1615 if (CompareUid(iUidType,anEntry.iType))
1622 if ((iAtt&KEntryAttAllowUid)==0 || anEntry.iAtt&KEntryAttDir || MatchUid())
1625 TBuf<KMaxFileName> driveAndPath=iFullName.DriveAndPath();
1626 fileName.Set(anEntry.iName,&driveAndPath,NULL);
1627 (*(CLocalMountCB*)&Mount()).ReadUidL(fileName.FullName(),anEntry);
1630 //#########################################################################################################################
1631 //## CLocalFormatCB class implementation
1632 //#########################################################################################################################
1634 CLocalFormatCB::CLocalFormatCB()
1638 CLocalFormatCB::~CLocalFormatCB()
1642 void CLocalFormatCB::DoFormatStepL()
1645 User::Leave(KErrNotSupported);
1649 //#########################################################################################################################
1650 //## CLocal File System class implementation
1651 //#########################################################################################################################
1656 // Create a new file system
1658 EXPORT_C CFileSystem* CreateFileSystem()
1668 TInt CLocal::Install()
1671 SetErrorMode(SEM_FAILCRITICALERRORS);
1672 EmulatorDiskSpeed(ReadSpeed, WriteSpeed);
1673 iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KF32BuildVersionNumber);
1674 _LIT(KWin32Name,"Win32");
1675 return(SetName(&KWin32Name));
1678 CMountCB* CLocal::NewMountL() const
1680 // Create a new mount control block.
1684 return(new(ELeave) CLocalMountCB);
1687 CFileCB* CLocal::NewFileL() const
1689 // Create a new file.
1693 return(new(ELeave) CLocalFileCB);
1696 CDirCB* CLocal::NewDirL() const
1698 // Create a new directory lister.
1701 return(new(ELeave) CLocalDirCB);
1704 CFormatCB* CLocal::NewFormatL() const
1706 // Create a new media formatter.
1709 return(new(ELeave) CLocalFormatCB);
1712 TInt CLocal::DefaultPath(TDes& aPath) const
1714 // Return the initial default path.
1718 aPath[0] = (TUint8) RFs::GetSystemDriveChar();
1722 void CLocal::DriveInfo(TDriveInfo& anInfo,TInt aDriveNumber) const
1724 // Return the drive info.
1730 // Get Fake drive info.
1731 if (aDriveNumber==EDriveZ)
1733 anInfo.iType=EMediaRom;
1734 anInfo.iMediaAtt=KMediaAttWriteProtected;
1735 anInfo.iDriveAtt=KDriveAttRom|KDriveAttInternal;
1736 anInfo.iConnectionBusType=EConnectionBusInternal;
1739 if (aDriveNumber==EDriveC)
1741 anInfo.iType=EMediaHardDisk;
1742 anInfo.iMediaAtt=KMediaAttVariableSize;
1743 anInfo.iDriveAtt=KDriveAttLocal|KDriveAttInternal;
1744 anInfo.iConnectionBusType=EConnectionBusInternal;
1748 if (MapDrive(envValue,aDriveNumber))
1750 anInfo.iType=EMediaHardDisk;
1751 anInfo.iDriveAtt=KDriveAttLocal|KDriveAttInternal;
1752 anInfo.iConnectionBusType=EConnectionBusInternal;
1755 anInfo.iType=EMediaNotPresent;