userlibandfileserver/fileserver/swins/elocal.cpp
changeset 0 a41df078684a
child 33 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "elocal.h"
       
    17 #include <emulator.h>
       
    18 #include <TCHAR.h>
       
    19 
       
    20 const TInt KMajorVersionNumber=1;
       
    21 const TInt KMinorVersionNumber=0;
       
    22 
       
    23 const TUint KInvalidSetFilePointer = 0xffffffff;	// INVALID_SET_FILE_POINTER
       
    24 
       
    25 #pragma data_seg(".data2")
       
    26 #ifdef __VC32__
       
    27 #pragma bss_seg(".data2")
       
    28 #endif
       
    29 static TInt ReadSpeed;
       
    30 static TInt WriteSpeed;
       
    31 #pragma data_seg()
       
    32 #ifdef __VC32__
       
    33 #pragma bss_seg()
       
    34 #endif
       
    35 
       
    36 static void Panic(TPanic aPanic)
       
    37 	{
       
    38 	User::Panic(_L("LocalFSys"),aPanic);
       
    39 	}
       
    40 
       
    41 
       
    42 //
       
    43 // Map aDrive to a path given by environment variables
       
    44 //
       
    45 TBool MapDrive(TDes& aFileName, TInt aDrive)
       
    46 	{
       
    47 
       
    48 	TDriveName root(TDriveUnit(aDrive).Name());
       
    49 	TFileName path;
       
    50 	TBuf<3> rootWithSlash(root);
       
    51 	rootWithSlash.Append('\\');
       
    52 
       
    53 	if (MapEmulatedFileName(path, rootWithSlash) == KErrNone)
       
    54 		{
       
    55 		aFileName=path.Left(3);	// drive letter, colon and backslash
       
    56 		return(ETrue);
       
    57 		}
       
    58 	aFileName=root;  // no trailing backslash
       
    59 	return(EFalse);
       
    60 	}
       
    61 	
       
    62 TInt MapFileName(TDes& aFileName, TInt aDrive, const TDesC& aName)
       
    63 	{
       
    64 	TFileName n(TDriveUnit(aDrive).Name());
       
    65 	n.Append(aName);
       
    66 	return MapEmulatedFileName(aFileName,n);
       
    67 	}
       
    68 
       
    69 void MapFileNameL(TDes& aFileName, TInt aDrive, const TDesC& aName)
       
    70 	{
       
    71 	User::LeaveIfError(MapFileName(aFileName,aDrive,aName));
       
    72 	}
       
    73 
       
    74 
       
    75 /**
       
    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.
       
    79 
       
    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 
       
    83 */
       
    84 LPCTSTR StrPtrZL(TDes16& aDes)
       
    85     {
       
    86     if(aDes.MaxLength() - aDes.Length() < 1)
       
    87         User::Leave(KErrBadName);  //-- no room for terminating zero
       
    88     
       
    89     return (LPCTSTR)aDes.PtrZ();
       
    90     }
       
    91 
       
    92 
       
    93 
       
    94 //
       
    95 // Converts a TTime structure to a Windows/NT filetime.  Assumes that aTime is a
       
    96 // UTC (system) time
       
    97 //
       
    98 static void timeToFileTimeL(const TTime& aTime,FILETIME* f)
       
    99 	{
       
   100 
       
   101 	TDateTime dateTime=aTime.DateTime();
       
   102 	SYSTEMTIME t;
       
   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));
       
   114 	}
       
   115 
       
   116 //
       
   117 //	Convert Windows/NT file time to TTime
       
   118 //	Assumes the NT file time is UTC
       
   119 //
       
   120 static void fileTimeToTime(FILETIME* f,TTime& aTime)
       
   121 	{
       
   122 	SYSTEMTIME t;
       
   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);
       
   125 	}
       
   126 
       
   127 //
       
   128 // Return the size and free space on a drive.
       
   129 //
       
   130 static TInt GetMediaSize(TInt aDriveNumber,TInt64& aSize,TInt64& aFree)
       
   131 	{
       
   132 
       
   133 	TBuf<4> driveName;
       
   134 	MapDrive(driveName,aDriveNumber);
       
   135 	DWORD sectorsPerCluster;
       
   136 	DWORD bytesPerSector;
       
   137 	DWORD freeClusters;
       
   138 	DWORD sizeClusters;
       
   139 	// this function should be upgraded to GetDiskFreeSpaceEx
       
   140 	BOOL b=Emulator::GetDiskFreeSpace((LPCTSTR)driveName.PtrZ(),&sectorsPerCluster,&bytesPerSector,&freeClusters,&sizeClusters);
       
   141 	if (!b)
       
   142 		return Emulator::LastError();
       
   143 
       
   144 	TInt64 bytesPerCluster=(TInt)(sectorsPerCluster*bytesPerSector);
       
   145 	aSize=TInt64((TInt)sizeClusters)*bytesPerCluster;
       
   146 	aFree=TInt64((TInt)freeClusters)*bytesPerCluster;
       
   147 	return(KErrNone);
       
   148 	}
       
   149 
       
   150 //
       
   151 // Return the volume name and uniqueID.
       
   152 //
       
   153 static TInt GetVolumeId(TInt aDriveNumber,TUint& aUniqueID)
       
   154 	{
       
   155 
       
   156 	TBuf<4> driveName;
       
   157 	MapDrive(driveName,aDriveNumber);
       
   158 	DWORD uniqueID,componentLength,flags;
       
   159 	BOOL b=Emulator::GetVolumeInformation((LPCTSTR)driveName.PtrZ(),NULL,0,&uniqueID,&componentLength,&flags,NULL,0);
       
   160 	if (!b)
       
   161 		return Emulator::LastError();
       
   162 
       
   163 	aUniqueID=uniqueID;
       
   164 	return(KErrNone);
       
   165 	}
       
   166 
       
   167 //#########################################################################################################################
       
   168 //##        CLocalMountCB class implementation
       
   169 //#########################################################################################################################
       
   170 
       
   171 
       
   172 CLocalMountCB::CLocalMountCB()
       
   173 	{
       
   174 	}
       
   175 
       
   176 CLocalMountCB::~CLocalMountCB()
       
   177 	{
       
   178 	}
       
   179 
       
   180 
       
   181 //
       
   182 // Returns ETrue if the drive == EDriveZ
       
   183 //
       
   184 TBool CLocalMountCB::IsRomDrive() const
       
   185 	{
       
   186 	// WINS emulated rom drive is Z:
       
   187 	return(Drive().DriveNumber()==EDriveZ);
       
   188 	}
       
   189 
       
   190 //-------------------------------------------------------------------------------------------------------------------
       
   191 
       
   192 /**
       
   193 Mount a volume. 
       
   194 
       
   195 @param aForceMount Flag to indicate whether mount should be forced to succeed if an error occurs
       
   196 @leave KErrNoMemory,KErrNotReady,KErrCorrupt,KErrUnknown.
       
   197 */
       
   198 void CLocalMountCB::MountL(TBool /*aForceMount*/)
       
   199 	{
       
   200 	TInt64 s,f;
       
   201 	const TInt driveNum=Drive().DriveNumber();
       
   202 	User::LeaveIfError(GetMediaSize(driveNum,s,f));
       
   203 	
       
   204     iSize=s;
       
   205     if (driveNum==EDriveZ)
       
   206 		iSize=4*1048576;
       
   207 	
       
   208     User::LeaveIfError(GetVolumeId(driveNum,iUniqueID));
       
   209 	SetVolumeName(HBufC::NewL(0));	// all Win32 volumes are unnamed
       
   210 	
       
   211     //-- assign default value, 4G-1
       
   212     iMaxFileSizeSupported = ((TUint64)4 << 30)-1;
       
   213 
       
   214         {
       
   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);
       
   220 
       
   221         TCHAR rootName[10];
       
   222         TCHAR volName[30];
       
   223         TCHAR volFSFileName[30];
       
   224         DWORD volSerNum;
       
   225         DWORD volMaxCompLen;
       
   226         DWORD volFsFlags;
       
   227         
       
   228         memset(rootName, 0, sizeof(rootName));
       
   229         wcsncpy(rootName, bufWinDrive.Ptr(), 3); //- something like "k:\\"
       
   230 
       
   231         BOOL b = GetVolumeInformation(rootName, volName, sizeof(volName)/sizeof(TCHAR), &volSerNum, &volMaxCompLen, &volFsFlags, volFSFileName, sizeof(volFSFileName)/sizeof(TCHAR));
       
   232         if(b)
       
   233             {
       
   234             if(_wcsicmp(volFSFileName, _TEXT("NTFS")) == 0)
       
   235                 {//-- this is NTFS
       
   236                 iMaxFileSizeSupported = 0xFFFFFFF0000; //-- max. file size for NTFS
       
   237                 }
       
   238              else
       
   239                 {//-- theoretically other than FAT & NTFS filesystem are possible.. Figure yourself.
       
   240             }   }
       
   241         }
       
   242 
       
   243 
       
   244     }
       
   245 
       
   246 //-------------------------------------------------------------------------------------------------------------------
       
   247 /**
       
   248     Try remount this volume. Checks if the volume parameters remained the same as on original MountL() call, and
       
   249     if they are, re-initialises the mount. 
       
   250     @return KErrNone if the remount was OK
       
   251             system-wide error code otherwise
       
   252 */
       
   253 TInt CLocalMountCB::ReMount()
       
   254 	{
       
   255 
       
   256 	TInt d=Drive().DriveNumber();
       
   257 	TUint uniqueID;
       
   258 	TInt r=GetVolumeId(d,uniqueID);
       
   259 	if (r==KErrNone && uniqueID!=iUniqueID)
       
   260 		r=KErrGeneral;
       
   261 	return(r);
       
   262 	}
       
   263 
       
   264 //-------------------------------------------------------------------------------------------------------------------
       
   265 void CLocalMountCB::Dismounted()
       
   266 	{
       
   267     }
       
   268 
       
   269 //-------------------------------------------------------------------------------------------------------------------
       
   270 //
       
   271 // Return the volume info.
       
   272 //
       
   273 void CLocalMountCB::VolumeL(TVolumeInfo& aVolume) const
       
   274 	{
       
   275 
       
   276 	TInt64 s,f;
       
   277 	TInt driveNum=Drive().DriveNumber();
       
   278 	User::LeaveIfError(GetMediaSize(driveNum,s,f));
       
   279 	if (driveNum==EDriveZ)
       
   280 		aVolume.iFree=0;
       
   281 	else
       
   282 		aVolume.iFree=f;
       
   283 	}
       
   284 
       
   285 //-------------------------------------------------------------------------------------------------------------------
       
   286 //
       
   287 // Set the volume label. Not supported on Win32 volumes
       
   288 //
       
   289 void CLocalMountCB::SetVolumeL(TDes&)
       
   290 	{
       
   291 
       
   292 	User::Leave(IsRomDrive() ? KErrAccessDenied : KErrNotSupported);
       
   293 	}
       
   294 
       
   295 //-------------------------------------------------------------------------------------------------------------------
       
   296 //
       
   297 // Return the address of the file if it is in rom
       
   298 //
       
   299 void CLocalMountCB::IsFileInRom(const TDesC& aName,TUint8*& aFileStart)
       
   300 	{
       
   301 
       
   302 	aFileStart=NULL;
       
   303 	if (!IsRomDrive())
       
   304 		return;
       
   305 
       
   306 	TFileName n;
       
   307 	if (MapFileName(n,Drive().DriveNumber(),aName)!=KErrNone)
       
   308 		return;
       
   309 	
       
   310 	DWORD access=GENERIC_READ;
       
   311 	DWORD share=FILE_SHARE_WRITE|FILE_SHARE_READ;
       
   312 	DWORD create=OPEN_EXISTING;
       
   313 	HANDLE h=Emulator::CreateFile((LPCTSTR)n.PtrZ(),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
       
   314 	if (h==INVALID_HANDLE_VALUE)
       
   315 		return;
       
   316 
       
   317 	CLocalFileCB::RomAddress(aName, h, aFileStart);
       
   318 	CloseHandle(h);
       
   319 	}
       
   320 
       
   321 //-------------------------------------------------------------------------------------------------------------------
       
   322 /**
       
   323     Make a directory.
       
   324     @param aName full path to the directory to create. Name validity is checked by file server.
       
   325 */
       
   326 void CLocalMountCB::MkDirL(const TDesC& aName)
       
   327 	{
       
   328 
       
   329 	if (IsRomDrive())
       
   330 		User::Leave(KErrAccessDenied);
       
   331 	TFileName n;
       
   332 	MapFileNameL(n,Drive().DriveNumber(),aName);
       
   333 	BOOL b=Emulator::CreateDirectory(StrPtrZL(n),NULL);
       
   334 	
       
   335 	if (b)
       
   336 		return;
       
   337 	TInt r=Emulator::LastError();
       
   338 	if (r!=KErrAlreadyExists)
       
   339 		User::Leave(r);
       
   340 	TEntry e;
       
   341 	EntryL(aName,e);
       
   342 
       
   343 	if (e.IsDir())
       
   344 		User::Leave(KErrAlreadyExists);
       
   345 	else
       
   346 		User::Leave(KErrAccessDenied);
       
   347 	}
       
   348 
       
   349 //-------------------------------------------------------------------------------------------------------------------
       
   350 /**
       
   351     Remove a directory.
       
   352     @param aName directory name
       
   353 */
       
   354 void CLocalMountCB::RmDirL(const TDesC& aName)
       
   355 	{
       
   356 
       
   357 	if (IsRomDrive())
       
   358 		User::Leave(KErrAccessDenied);
       
   359 	
       
   360     TFileName n;
       
   361 	MapFileNameL(n,Drive().DriveNumber(),aName);
       
   362 	BOOL b=Emulator::RemoveDirectory(StrPtrZL(n));
       
   363 	
       
   364 	if (!b)
       
   365 		User::Leave(Emulator::LastError());
       
   366 	}
       
   367 
       
   368 //-------------------------------------------------------------------------------------------------------------------
       
   369 //
       
   370 // Delete a file.
       
   371 //
       
   372 void CLocalMountCB::DeleteL(const TDesC& aName)
       
   373 	{
       
   374 
       
   375 	if (IsRomDrive())
       
   376 		User::Leave(KErrAccessDenied);
       
   377 	TFileName n;
       
   378 	MapFileNameL(n,Drive().DriveNumber(),aName);
       
   379 	BOOL b=Emulator::DeleteFile(StrPtrZL(n));
       
   380 	
       
   381 	if (!b)
       
   382 		User::Leave(Emulator::LastError());
       
   383 	}
       
   384 
       
   385 //-------------------------------------------------------------------------------------------------------------------
       
   386 //
       
   387 // Rename a file or directory.
       
   388 //
       
   389 void CLocalMountCB::RenameL(const TDesC& aOldName,const TDesC& aNewName)
       
   390 	{
       
   391 
       
   392 	if (IsRomDrive())
       
   393 		User::Leave(KErrAccessDenied);
       
   394 	TEntry entry;
       
   395 	TRAPD(r,EntryL(aNewName,entry));
       
   396 	if (r!=KErrNone && r!=KErrNotFound)
       
   397 		User::Leave(r);
       
   398 	TFileName old;
       
   399 	MapFileNameL(old,Drive().DriveNumber(),aOldName);
       
   400 	TFileName n;
       
   401 	MapFileNameL(n,Drive().DriveNumber(),aNewName);
       
   402 	BOOL b=Emulator::MoveFile(StrPtrZL(old),StrPtrZL(n));
       
   403 	
       
   404 	if (!b)
       
   405 		User::Leave(Emulator::LastError());
       
   406 	}
       
   407 
       
   408 //-------------------------------------------------------------------------------------------------------------------
       
   409 void CLocalMountCB::ReplaceL(const TDesC& aOldName,const TDesC& aNewName)
       
   410 //
       
   411 // Delete aNewName if it exists and rename anOldName.
       
   412 //
       
   413 	{
       
   414 
       
   415 	if (IsRomDrive())
       
   416 		User::Leave(KErrAccessDenied);
       
   417 	TEntry entry;
       
   418 	if(FileNamesIdentical(aOldName,aNewName))
       
   419 		{
       
   420 		return;
       
   421 		}
       
   422 	TRAPD(r,DeleteL(aNewName));
       
   423 	if (r!=KErrNotFound && r!=KErrNone)
       
   424 		User::Leave(r);
       
   425 	TFileName old;
       
   426 	MapFileNameL(old,Drive().DriveNumber(),aOldName);
       
   427 	TFileName n;
       
   428 	MapFileNameL(n,Drive().DriveNumber(),aNewName);
       
   429 	BOOL b=Emulator::MoveFile(StrPtrZL(old),StrPtrZL(n));
       
   430 	if (!b)
       
   431 		User::Leave(Emulator::LastError());
       
   432 	}
       
   433 	
       
   434 //-------------------------------------------------------------------------------------------------------------------
       
   435 //
       
   436 //	Set and get file pointer for windows files
       
   437 //	
       
   438 static DWORD SetFilePointerL(HANDLE hFile,LONG lDistanceToMove,DWORD dwMoveMethod)
       
   439 	
       
   440 	{
       
   441 	DWORD dwRet;
       
   442 	
       
   443 	dwRet=SetFilePointer(hFile,lDistanceToMove,0,dwMoveMethod);
       
   444 	if (dwRet==KInvalidSetFilePointer)	//	INVALID_HANDLE_VALUE
       
   445 		User::Leave(Emulator::LastError());
       
   446 
       
   447 	return (dwRet);	
       
   448 	}
       
   449 
       
   450 //-------------------------------------------------------------------------------------------------------------------
       
   451 //
       
   452 //	Set and get file pointer for windows files
       
   453 //	
       
   454 static DWORD SetFilePointer64L(HANDLE hFile, LARGE_INTEGER * lpDistanceToMove, DWORD dwMoveMethod)
       
   455 	{
       
   456 
       
   457 	DWORD dwRet;
       
   458 	
       
   459 	dwRet=SetFilePointer(hFile, lpDistanceToMove->LowPart, &(lpDistanceToMove->HighPart), dwMoveMethod);
       
   460 	
       
   461     TInt r = Emulator::LastError();
       
   462 	if ((KInvalidSetFilePointer==dwRet) && (r != NO_ERROR))	
       
   463 		User::Leave(r);
       
   464 
       
   465 	return (dwRet);	
       
   466 	}
       
   467 
       
   468 //-------------------------------------------------------------------------------------------------------------------
       
   469 /**
       
   470     Read file section without opening this file on a file server side.
       
   471     
       
   472     @param  aName       file name; all trailing dots from the name will be removed
       
   473     @param  aFilePos    start read position within a file
       
   474     @param  aLength     how many bytes to read; on return will be how many bytes actually read
       
   475     @param  aDes        local buffer desctriptor
       
   476     @param  aMessage    from file server, used to write data to the buffer in different address space.
       
   477 
       
   478     @leave on media read error
       
   479 */
       
   480 void CLocalMountCB::ReadSectionL(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
       
   481 	{
       
   482 	
       
   483 	TFileName n;
       
   484 	MapFileNameL(n,Drive().DriveNumber(),aName);
       
   485 	
       
   486 	WIN32_FIND_DATA d;
       
   487 	HANDLE hFile=Emulator::FindFirstFile(StrPtrZL(n),&d);
       
   488 	if (hFile==INVALID_HANDLE_VALUE)
       
   489 		User::Leave(Emulator::LastError());
       
   490 	FOREVER
       
   491 		{
       
   492 		TPtrC fileName((TText*)(&d.cFileName[0]));
       
   493 		if (fileName!=_L(".") && fileName!=_L(".."))
       
   494 			break;
       
   495 		if (!Emulator::FindNextFile(hFile,&d))
       
   496 			{
       
   497 			TInt r = Emulator::LastError();
       
   498 			User::Leave(r == KErrEof ? KErrNotFound : r);
       
   499 			}
       
   500 		}
       
   501 	
       
   502 	FindClose(hFile);
       
   503 		
       
   504 	hFile=Emulator::CreateFile(StrPtrZL(n),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
       
   505 	if (hFile==INVALID_HANDLE_VALUE)
       
   506 		return;
       
   507 
       
   508 	DWORD dwSizeLow, dwSizeHigh;
       
   509 	dwSizeLow=GetFileSize(hFile,&dwSizeHigh);
       
   510 	TInt r = Emulator::LastError();
       
   511 	if((NO_ERROR != r) && (INVALID_FILE_SIZE == dwSizeLow))
       
   512 		User::Leave(r);
       
   513 	
       
   514 	// ReadSectionL can support only upto 2G as aPos is TInt!
       
   515 	const TInt64 fileSize = MAKE_TINT64(dwSizeHigh, dwSizeHigh);
       
   516 	if(fileSize > KMaxTInt)
       
   517 		{
       
   518 		if (!CloseHandle(hFile))
       
   519 			User::Leave(Emulator::LastError());
       
   520 
       
   521 		User::Leave(KErrTooBig);
       
   522 		}
       
   523 	
       
   524 //	Check that reading from aPos for aLength lies within the file
       
   525 //	if aPos is within the file, and aLength is too long, read up to EOF
       
   526 //	If aPos is beyond the file, return a zero length descriptor
       
   527 
       
   528 	if ((TInt)dwSizeLow>=(aPos+aLength))	//	Can read entire length requested from aPos	
       
   529 		SetFilePointerL(hFile,aPos,FILE_BEGIN);			
       
   530 	
       
   531 	else if ((TInt)dwSizeLow>aPos)		//	Can read from aPos but not entire length requested
       
   532 		{
       
   533 		SetFilePointerL(hFile,aPos,FILE_BEGIN);
       
   534 		aLength=dwSizeLow-aPos;
       
   535 		}	
       
   536 	else						//	Cannot read from aPos because it lies outside file
       
   537 		{						//	Close file and leave with KErrEof
       
   538 		if (!CloseHandle(hFile))
       
   539 			User::Leave(Emulator::LastError());
       
   540 
       
   541 		User::Leave(KErrEof);
       
   542 		}
       
   543 
       
   544 	TBuf8<0x1000> buf;
       
   545 	TInt pos=0;
       
   546 
       
   547 	if (aMessage.Handle() == KLocalMessageHandle)
       
   548 		((TPtr8* )aTrg)->SetLength(0);
       
   549 	
       
   550 	while (aLength)
       
   551 		{
       
   552 		TInt readTotal=Min(aLength,buf.MaxLength());
       
   553 		DWORD ret;
       
   554 		BOOL b=ReadFile(hFile,(TAny*)buf.Ptr(),readTotal,&ret,NULL);
       
   555 		if (!b || ((TInt)ret!=readTotal))	
       
   556 			User::Leave(Emulator::LastError());
       
   557 		buf.SetLength(ret);
       
   558 		
       
   559 		if(aMessage.Handle() == KLocalMessageHandle)
       
   560 			((TPtr8* )aTrg)->Append(buf);
       
   561 		else
       
   562 			aMessage.WriteL(0,buf,pos);
       
   563 	
       
   564 		pos+=ret;
       
   565 		if (((TInt)ret)<readTotal)
       
   566 			break;
       
   567 		aLength-=readTotal;
       
   568 		}
       
   569 			
       
   570 	if (!CloseHandle(hFile))
       
   571 		User::Leave(Emulator::LastError());
       
   572 	}
       
   573 
       
   574 
       
   575 //-------------------------------------------------------------------------------------------------------------------
       
   576 //
       
   577 // Read the entry uid if present
       
   578 //
       
   579 void CLocalMountCB::ReadUidL(const TDesC& aName,TEntry& anEntry) const
       
   580 	{
       
   581 
       
   582 //  First check to see if the first sixteen bytes form a valid UID
       
   583 	TBuf<KMaxFileName + 1> fileName=aName;
       
   584 	HANDLE hFile=Emulator::CreateFile(StrPtrZL(fileName),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
       
   585 	if (hFile==INVALID_HANDLE_VALUE)
       
   586 		return;
       
   587 	DWORD ret;
       
   588 	TBuf8<sizeof(TCheckedUid)> checkedUidBuf;
       
   589 	checkedUidBuf.SetLength(sizeof(TCheckedUid));
       
   590 	ReadFile(hFile,&checkedUidBuf[0],sizeof(TCheckedUid),&ret,NULL);
       
   591 	if (ret!=sizeof(TCheckedUid))
       
   592 		goto close;
       
   593 	{
       
   594 	TCheckedUid checkedUid(checkedUidBuf);
       
   595 	if(checkedUid.UidType()!=TUidType(TUid::Null(),TUid::Null(),TUid::Null()))
       
   596 		{
       
   597 		anEntry.iType=checkedUid.UidType();
       
   598 		goto close;
       
   599 		}
       
   600 	}
       
   601 
       
   602 //Look at PE file for UID section
       
   603 		{
       
   604 		const TInt KPeHeaderAddrAddr=0x3c;
       
   605 		const TInt KPeHeaderAddrSize=0x01;
       
   606 		const TInt KNumberOfSectionsOffset=0x06;
       
   607 		const TInt KNumberOfSectionsSize=0x02;
       
   608 		const TInt KSectionTableOffset=0xf8;
       
   609 		const TInt KSectionHeaderSize=0x28;
       
   610 		const TInt KSectionNameLength=0x08;
       
   611 		const TInt KPtrToRawDataOffset=0x14;
       
   612 		const TInt KPtrToRawDataSize=0x04;
       
   613 		const TText8 peText[4]={'P','E',0,0};
       
   614 		const TText8 uidText[8]={'.','S','Y','M','B','I','A','N'};
       
   615 		
       
   616 	//Read address of start of PE header
       
   617 		if (SetFilePointer(hFile,KPeHeaderAddrAddr,0,FILE_BEGIN)==KInvalidSetFilePointer)
       
   618 			goto close;
       
   619 		TInt peAddr=0;
       
   620 		ReadFile(hFile,&peAddr,KPeHeaderAddrSize,&ret,NULL);
       
   621 		if (ret!=KPeHeaderAddrSize)
       
   622 			goto close;
       
   623 		
       
   624 	//Check it really is the start of PE header
       
   625 		if (SetFilePointer(hFile,peAddr,0,FILE_BEGIN)==KInvalidSetFilePointer)
       
   626 			goto close;
       
   627 		TText8 text[4];
       
   628 		ReadFile(hFile,text,4,&ret,NULL);
       
   629 		if (*(TInt32*)text!=*(TInt32*)peText)
       
   630 			goto close;
       
   631 		
       
   632 	//Read number of sections
       
   633 		if (SetFilePointer(hFile,peAddr+KNumberOfSectionsOffset,0,FILE_BEGIN)==KInvalidSetFilePointer)
       
   634 			goto close;
       
   635 		TInt sections=0;
       
   636 		ReadFile(hFile,&sections,KNumberOfSectionsSize,&ret,NULL);
       
   637 		if (ret!=KNumberOfSectionsSize)
       
   638 			goto close;
       
   639 
       
   640 	//Go through section headers looking for UID section
       
   641 		if (SetFilePointer(hFile,peAddr+KSectionTableOffset,0,FILE_BEGIN)==KInvalidSetFilePointer)
       
   642 			goto close;
       
   643 		TInt i=0;
       
   644 		for(;i<sections;i++)
       
   645 			{
       
   646 			TText8 name[KSectionNameLength];
       
   647 			ReadFile(hFile,name,KSectionNameLength,&ret,NULL);
       
   648 			if (ret!=KSectionNameLength)
       
   649 				goto close;
       
   650 			if (*(TInt64*)name==*(TInt64*)uidText)
       
   651 				break;
       
   652 			if (SetFilePointer(hFile,KSectionHeaderSize-KSectionNameLength,0,FILE_CURRENT)==KInvalidSetFilePointer)
       
   653 				goto close;
       
   654 			}
       
   655 		if (i==sections)
       
   656 			goto close;
       
   657 
       
   658 	//Read RVA/Offset
       
   659 		if (SetFilePointer(hFile,KPtrToRawDataOffset-KSectionNameLength,0,FILE_CURRENT)==KInvalidSetFilePointer)
       
   660 			goto close;
       
   661 		TInt uidOffset;
       
   662 		ReadFile(hFile,&uidOffset,KPtrToRawDataSize,&ret,NULL);
       
   663 		if (ret!=KPtrToRawDataSize)
       
   664 			goto close;
       
   665 
       
   666 	//Read UIDs!
       
   667 		if (SetFilePointer(hFile,uidOffset,0,FILE_BEGIN)==KInvalidSetFilePointer)
       
   668 			User::Leave(KErrGeneral);
       
   669 
       
   670 		TEmulatorImageHeader header;
       
   671 		ReadFile(hFile,&header,sizeof(header),&ret,NULL);
       
   672 		if (ret==sizeof(header))
       
   673 			anEntry.iType=*(TUidType*)&header;
       
   674 		}
       
   675 //Close file
       
   676 close:
       
   677 	if (!CloseHandle(hFile))
       
   678 		User::Leave(Emulator::LastError());
       
   679 	}
       
   680 
       
   681 //-------------------------------------------------------------------------------------------------------------------
       
   682 /**
       
   683     Try to find a directory entry by the given name and path. 
       
   684     This method _must_ leave if the entry is not found. See the caller.
       
   685 
       
   686     @param  aName   path to the directory object. all trailing dots from the name will be removed.
       
   687     @param  anEntry on return will contain the entry data
       
   688     
       
   689     @leave  KErrPathNotFound if there is no path to the aName
       
   690             KErrNotFound     if the entry corresponding to the aName is not found
       
   691             system-wide erorr code of media read failure.
       
   692 */
       
   693 void CLocalMountCB::EntryL(const TDesC& aName,TEntry& anEntry) const
       
   694 	{
       
   695 
       
   696 	TFileName n;
       
   697 	MapFileNameL(n,Drive().DriveNumber(),aName);
       
   698 	WIN32_FIND_DATA d;
       
   699 	HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&d);
       
   700 	if (h==INVALID_HANDLE_VALUE)
       
   701 		User::Leave(Emulator::LastError());
       
   702 	FOREVER
       
   703 		{
       
   704 		TPtrC fileName((TText*)(&d.cFileName[0]));
       
   705 		if (fileName!=_L(".") && fileName!=_L(".."))
       
   706 			break;
       
   707 		if (!Emulator::FindNextFile(h,&d))
       
   708 			{
       
   709 			TInt r = Emulator::LastError();
       
   710 			User::Leave(r == KErrEof ? KErrNotFound : r);
       
   711 			}
       
   712 		}
       
   713 	FindClose(h);
       
   714 	anEntry.iName.Des()=(TText*)(&d.cFileName[0]);
       
   715 	anEntry.iAtt=d.dwFileAttributes&KEntryAttMaskSupported;
       
   716 	if (IsRomDrive())
       
   717 		anEntry.iAtt|=KEntryAttReadOnly;
       
   718 
       
   719 	anEntry.SetFileSize(MAKE_TINT64(d.nFileSizeHigh,d.nFileSizeLow));
       
   720 
       
   721 	fileTimeToTime(&d.ftLastWriteTime,anEntry.iModified);
       
   722 	ReadUidL(n,anEntry);
       
   723 	}
       
   724 
       
   725 //-------------------------------------------------------------------------------------------------------------------
       
   726 /**
       
   727     Set directory entry details.
       
   728     @param  aName           entry name; all trailing dots from the name will be removed
       
   729     @param  aTime           entry modification time (and last access as well)
       
   730     @param  aSetAttMask     entry attributes OR mask
       
   731     @param  aClearAttMask   entry attributes AND mask
       
   732 
       
   733 */
       
   734 void CLocalMountCB::SetEntryL(const TDesC& aName,const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
       
   735 	{
       
   736 
       
   737 	if (IsRomDrive())
       
   738 		User::Leave(KErrAccessDenied);
       
   739 	TFileName n;
       
   740 	MapFileNameL(n,Drive().DriveNumber(),aName);
       
   741 	TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
       
   742 	DWORD att=Emulator::GetFileAttributes(StrPtrZL(n));
       
   743 	if (att==0xffffffffu)
       
   744 		User::Leave(Emulator::LastError());
       
   745 	
       
   746     if (setAttMask|aClearAttMask)
       
   747 		{
       
   748 		att|=setAttMask;
       
   749 		att&=(~aClearAttMask);
       
   750 		if (!Emulator::SetFileAttributes((LPCTSTR)n.Ptr(),att))
       
   751 			User::Leave(Emulator::LastError());
       
   752 		}
       
   753 	
       
   754     if (aSetAttMask&KEntryAttModified)
       
   755 		{
       
   756 		FILETIME f;
       
   757 		timeToFileTimeL(aTime,&f);
       
   758 
       
   759 		if (att&KEntryAttReadOnly)
       
   760 			{
       
   761 			DWORD writeableAtt=att&(~KEntryAttReadOnly);
       
   762 			if (!Emulator::SetFileAttributes((LPCTSTR)n.Ptr(),writeableAtt))
       
   763 				User::Leave(Emulator::LastError());
       
   764 			}
       
   765 
       
   766 		HANDLE h;
       
   767 		if (att&KEntryAttDir)
       
   768 			{
       
   769 			h=Emulator::CreateFile((LPCTSTR)n.Ptr(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_DIRECTORY|FILE_FLAG_BACKUP_SEMANTICS, NULL);
       
   770 			if (h==INVALID_HANDLE_VALUE)
       
   771 				User::Leave(Emulator::LastError());
       
   772 			}
       
   773 		else
       
   774 			{
       
   775 			h=Emulator::CreateFile((LPCTSTR)n.Ptr(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
       
   776 			if (h==INVALID_HANDLE_VALUE)
       
   777 				User::Leave(Emulator::LastError());
       
   778 			}
       
   779 
       
   780 		if (!SetFileTime(h,NULL,&f,&f))
       
   781 			{
       
   782 			TInt error = Emulator::LastError(); 
       
   783 			CloseHandle(h);
       
   784 			User::Leave(error);
       
   785 			}
       
   786 		
       
   787         if (!CloseHandle(h))
       
   788 			User::Leave(Emulator::LastError());
       
   789 		
       
   790         if ((att&KEntryAttReadOnly) && !Emulator::SetFileAttributes((LPCTSTR)n.Ptr(),att))
       
   791 			User::Leave(Emulator::LastError());
       
   792 		}
       
   793 	}
       
   794 
       
   795 //-------------------------------------------------------------------------------------------------------------------
       
   796 /**
       
   797     Open/Create/Replace a file on the current mount.
       
   798     
       
   799     @param  aName   file name; all trailing dots from the name will be removed
       
   800     @param  aMode   File open mode, See TFileMode
       
   801     @param  anOpen  specifies action: open, create or replace the file
       
   802     @param  aFile   pointer to the CFileCB object to populate
       
   803 
       
   804 */
       
   805 void CLocalMountCB::FileOpenL(const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB* aFile)
       
   806 	{
       
   807 
       
   808 	if (IsRomDrive() && (anOpen!=EFileOpen || (aMode&EFileWrite)))
       
   809 		User::Leave(KErrAccessDenied);
       
   810 	TFileName n;
       
   811 	MapFileNameL(n,Drive().DriveNumber(),aName);
       
   812 	
       
   813 	DWORD access=GENERIC_READ|GENERIC_WRITE;
       
   814 	DWORD share=FILE_SHARE_WRITE|FILE_SHARE_READ;
       
   815 	DWORD create=0;
       
   816 	switch (anOpen)
       
   817 		{
       
   818 	    case EFileOpen: create=OPEN_EXISTING; break;
       
   819 	    case EFileCreate: create=CREATE_NEW; break;
       
   820 	    case EFileReplace: create=CREATE_ALWAYS; break;
       
   821 		}
       
   822 
       
   823 	HANDLE h=Emulator::CreateFile(StrPtrZL(n),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
       
   824 	
       
   825 	if((h==INVALID_HANDLE_VALUE) && !(aMode&EFileWrite))
       
   826 	{
       
   827 	// If windows will not allow write access and it was not requested then open for read only
       
   828 	access=GENERIC_READ;
       
   829 	h=Emulator::CreateFile(StrPtrZL(n),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
       
   830 	}
       
   831 
       
   832 	if (h==INVALID_HANDLE_VALUE)
       
   833 		User::Leave(Emulator::LastError());
       
   834 	CLocalFileCB& file=(*((CLocalFileCB*)aFile));
       
   835 	file.SetHandle(h);
       
   836 	
       
   837     BY_HANDLE_FILE_INFORMATION info;
       
   838 	if (!GetFileInformationByHandle(h,&info))
       
   839 		User::Leave(Emulator::LastError());
       
   840 	
       
   841     const TUint64 fileSize = MAKE_TUINT64(info.nFileSizeHigh, info.nFileSizeLow);
       
   842 	
       
   843     // Check on file size
       
   844 	if(MaxFileSizeSupported() < fileSize)
       
   845 		User::Leave(KErrTooBig);
       
   846 	
       
   847     file.SetMaxSupportedSize(MaxFileSizeSupported());
       
   848     file.SetSize64(fileSize, EFalse);
       
   849 	file.SetAtt(info.dwFileAttributes&KEntryAttMaskSupported);
       
   850 
       
   851 //	if (IsRomDrive())
       
   852 //		file.iAtt|=KEntryAttReadOnly;
       
   853 	TTime tempTime=file.Modified();
       
   854 	fileTimeToTime(&info.ftLastWriteTime,tempTime);
       
   855 	file.SetModified(tempTime);
       
   856 	}
       
   857 
       
   858 void AppendAsteriskL(TDes& aDes)
       
   859 	{
       
   860 	if (aDes.Length()==aDes.MaxLength())
       
   861 		User::Leave(KErrBadName);
       
   862 	aDes.Append('*');
       
   863 	}
       
   864 
       
   865 //-------------------------------------------------------------------------------------------------------------------	
       
   866 /**
       
   867     Open a directory on the current mount.
       
   868     
       
   869     @param  aName   path to the object in the directory we want to open; all trailing dots from the name will be removed
       
   870     @param  aDir    dir. CB to be filled in.
       
   871     
       
   872     If there is no such a path, this method must leave with KErrPathNotFound
       
   873 
       
   874     @leave  KErrPathNotFound if thereis no such path
       
   875     @leave  error code on media read fault
       
   876 */
       
   877 void CLocalMountCB::DirOpenL(const TDesC& aName,CDirCB* aDir)
       
   878 	{
       
   879 
       
   880 	TFileName n;
       
   881 	TParse parse;
       
   882 	MapFileNameL(n,Drive().DriveNumber(),aName);
       
   883 	parse.Set(n,NULL,NULL);
       
   884 	n=parse.DriveAndPath();
       
   885 	AppendAsteriskL(n);
       
   886 	WIN32_FIND_DATA info;
       
   887 	HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&info);
       
   888 	if (h==INVALID_HANDLE_VALUE)
       
   889 		{
       
   890 		TInt error=Emulator::LastError();
       
   891 		TParse parser;
       
   892 		TInt r=parser.Set(n,NULL,NULL);
       
   893 		if (r!=KErrNone)
       
   894 			User::Leave(r);
       
   895 		if (!parser.IsRoot() || Drive().DriveNumber()!=0 || error!=KErrNotFound)
       
   896 			User::Leave(error);
       
   897 		h=NULL;
       
   898 		}
       
   899 	CLocalDirCB& dir=(*((CLocalDirCB*)aDir));
       
   900 	dir.SetHandle(h);
       
   901 	dir.SetPending(ETrue);
       
   902 	dir.iEntry.iName.Des()=(TText*)(&info.cFileName[0]);
       
   903 	dir.iEntry.iAtt=info.dwFileAttributes&KEntryAttMaskSupported;
       
   904 
       
   905 	const TInt64 fileSize = MAKE_TINT64(info.nFileSizeHigh,info.nFileSizeLow);
       
   906 	dir.iEntry.SetFileSize(fileSize);
       
   907 
       
   908 	n=parse.FullName();
       
   909 	if (parse.NameAndExt().Length()==0)
       
   910 		AppendAsteriskL(n);
       
   911 	dir.SetFullName(n);
       
   912 	fileTimeToTime(&info.ftLastWriteTime,dir.iEntry.iModified);
       
   913 	}
       
   914 
       
   915 //-------------------------------------------------------------------------------------------------------------------	
       
   916 //
       
   917 // Read directly from disk
       
   918 //
       
   919 void CLocalMountCB::RawReadL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aDes*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) const
       
   920 	{
       
   921 	User::Leave(KErrNotSupported);
       
   922 	}
       
   923 
       
   924 //-------------------------------------------------------------------------------------------------------------------	
       
   925 //
       
   926 // Write directly to disk
       
   927 //
       
   928 void CLocalMountCB::RawWriteL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aDes*/ ,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/)
       
   929 	{
       
   930 	User::Leave(KErrNotSupported);
       
   931 	}
       
   932 
       
   933 //-------------------------------------------------------------------------------------------------------------------	
       
   934 //
       
   935 // Get the short name associated with aLongName
       
   936 //
       
   937 void CLocalMountCB::GetShortNameL(const TDesC& aLongName,TDes& aShortName)
       
   938 	{
       
   939 
       
   940 	if (IsRomDrive())
       
   941 		User::Leave(KErrNotSupported);
       
   942 
       
   943 	TFileName n;
       
   944 	MapFileNameL(n,Drive().DriveNumber(),aLongName);
       
   945 	WIN32_FIND_DATA d;
       
   946 	HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&d);
       
   947 	if (h==INVALID_HANDLE_VALUE)
       
   948 		User::Leave(Emulator::LastError());
       
   949 	FindClose(h);
       
   950 	if (d.cAlternateFileName[0])	// we have a dos name too
       
   951 		aShortName=(TText*)(&d.cAlternateFileName[0]);
       
   952 	else
       
   953 		aShortName=(TText*)(&d.cFileName[0]);
       
   954 	}
       
   955 
       
   956 //-------------------------------------------------------------------------------------------------------------------	
       
   957 //
       
   958 // Get the short name associated with aLongName
       
   959 //
       
   960 void CLocalMountCB::GetLongNameL(const TDesC& aShortName,TDes& aLongName)
       
   961 	{
       
   962 
       
   963 	if (IsRomDrive())
       
   964 		User::Leave(KErrNotSupported);
       
   965 
       
   966 	TFileName n;
       
   967 	MapFileNameL(n,Drive().DriveNumber(),aShortName);
       
   968 	WIN32_FIND_DATA d;
       
   969 	HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&d);
       
   970 	if (h==INVALID_HANDLE_VALUE)
       
   971 		User::Leave(Emulator::LastError());
       
   972 	FindClose(h);
       
   973 	aLongName=(TText*)(&d.cFileName[0]);
       
   974 	}
       
   975 
       
   976 //-------------------------------------------------------------------------------------------------------------------	
       
   977 /**
       
   978 Reports whether the specified interface is supported - if it is,
       
   979 the supplied interface object is modified to it
       
   980 
       
   981 @param aInterfaceId     The interface of interest
       
   982 @param aInterface       The interface object
       
   983 @return                 KErrNone if the interface is supported, otherwise KErrNotFound 
       
   984 
       
   985 @see CMountCB::GetInterface()
       
   986 */
       
   987 TInt CLocalMountCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
       
   988     {
       
   989 	switch(aInterfaceId)
       
   990 		{
       
   991 		case EFileExtendedInterface:
       
   992 			((CMountCB::MFileExtendedInterface*&) aInterface) = this;
       
   993 			return KErrNone;
       
   994 
       
   995     	case ELocalBufferSupport:
       
   996     		// CLocalMountCB doesn't ever use any extensions?
       
   997 	    	// 	- seems to not have any iProxyDrive or LocalDrive() or similar, 
       
   998     		// so we'll just return KErrNone here.
       
   999    			return KErrNone;
       
  1000 
       
  1001 		default:
       
  1002 		    return CMountCB::GetInterface(aInterfaceId,aInterface,aInput);
       
  1003 		}
       
  1004     }
       
  1005 
       
  1006 //-------------------------------------------------------------------------------------------------------------------	
       
  1007 TInt CLocalMountCB::LocalBufferSupport()
       
  1008 	{
       
  1009 	TAny* dummyInterface = NULL;
       
  1010 	TAny* dummyInput = NULL;
       
  1011 	return GetInterface(ELocalBufferSupport,dummyInterface,dummyInput);
       
  1012 	}
       
  1013 
       
  1014 //-------------------------------------------------------------------------------------------------------------------	
       
  1015 /**
       
  1016     Read file section without opening this file on a file server side.
       
  1017     
       
  1018     @param  aName       file name; all trailing dots from the name will be removed
       
  1019     @param  aFilePos    start read position within a file
       
  1020     @param  aLength     how many bytes to read; on return will be how many bytes actually read
       
  1021     @param  aDes        local buffer desctriptor
       
  1022     @param  aMessage    from file server, used to write data to the buffer in different address space.
       
  1023 
       
  1024     @leave on media read error
       
  1025 */
       
  1026 void CLocalMountCB::ReadSection64L(const TDesC& aName, TInt64 aPos, TAny* aTrg, TInt aLength, const RMessagePtr2& aMessage)
       
  1027 	{
       
  1028 	TFileName n;
       
  1029 	MapFileNameL(n,Drive().DriveNumber(),aName);
       
  1030 	
       
  1031 	WIN32_FIND_DATA d;
       
  1032 	HANDLE hFile=Emulator::FindFirstFile(StrPtrZL(n),&d);
       
  1033 	if (hFile==INVALID_HANDLE_VALUE)
       
  1034 		User::Leave(Emulator::LastError());
       
  1035 	
       
  1036 	FOREVER
       
  1037 		{
       
  1038 		TPtrC fileName((TText*)(&d.cFileName[0]));
       
  1039 		if (fileName!=_L(".") && fileName!=_L(".."))
       
  1040 			break;
       
  1041 		if (!Emulator::FindNextFile(hFile,&d))
       
  1042 			{
       
  1043 			TInt r = Emulator::LastError();
       
  1044 			User::Leave(r == KErrEof ? KErrNotFound : r);
       
  1045 			}
       
  1046 		}
       
  1047 	
       
  1048 	FindClose(hFile);
       
  1049 	
       
  1050 	hFile=Emulator::CreateFile(StrPtrZL(n),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
       
  1051 	if (hFile==INVALID_HANDLE_VALUE)
       
  1052 		return;
       
  1053 
       
  1054 	DWORD dwSizeLow, dwSizeHigh;
       
  1055 	dwSizeLow=GetFileSize(hFile,&dwSizeHigh);
       
  1056 	TInt r = Emulator::LastError();
       
  1057 	if((NO_ERROR != r) && (INVALID_FILE_SIZE == dwSizeLow))
       
  1058 		User::Leave(r);
       
  1059 	
       
  1060 	// Check on file size 
       
  1061 	const TInt64 fileSize = MAKE_TINT64(dwSizeHigh, dwSizeLow);
       
  1062 	if(MaxFileSizeSupported() < (TUint64)fileSize)
       
  1063 		{
       
  1064 		if (!CloseHandle(hFile))
       
  1065 			User::Leave(Emulator::LastError());
       
  1066 		
       
  1067         User::Leave(KErrTooBig);
       
  1068 		}
       
  1069 	
       
  1070 //	Check that reading from aPos for aLength lies within the file
       
  1071 //	if aPos is within the file, and aLength is too long, read up to EOF
       
  1072 //	If aPos is beyond the file, return a zero length descriptor
       
  1073 
       
  1074 	if (fileSize>=aPos+aLength)	//	Can read entire length requested from aPos	
       
  1075 		SetFilePointer64L(hFile,(LARGE_INTEGER *)&aPos,FILE_BEGIN);
       
  1076 	
       
  1077 	else if (fileSize>aPos)		//	Can read from aPos but not entire length requested
       
  1078 		{
       
  1079 		SetFilePointer64L(hFile,(LARGE_INTEGER *)&aPos,FILE_BEGIN);
       
  1080 		aLength=(TInt)(fileSize-aPos);
       
  1081 		}	
       
  1082 	else						//	Cannot read from aPos because it lies outside file
       
  1083 		{						//	Close file and leave with KErrEof
       
  1084 		if (!CloseHandle(hFile))
       
  1085 			User::Leave(Emulator::LastError());
       
  1086 
       
  1087 		User::Leave(KErrEof);
       
  1088 		}
       
  1089 
       
  1090 	TBuf8<0x1000> buf;
       
  1091 	TInt pos=0;
       
  1092 
       
  1093 	if (aMessage.Handle() == KLocalMessageHandle)
       
  1094 		((TPtr8* )aTrg)->SetLength(0);
       
  1095 	
       
  1096 	while (aLength)
       
  1097 		{
       
  1098 		TInt readTotal=Min(aLength,buf.MaxLength());
       
  1099 		DWORD ret;
       
  1100 		BOOL b=ReadFile(hFile,(TAny*)buf.Ptr(),readTotal,&ret,NULL);
       
  1101 		if (!b || ((TInt)ret!=readTotal))	
       
  1102 			User::Leave(Emulator::LastError());
       
  1103 		buf.SetLength(ret);
       
  1104 		
       
  1105 		if(aMessage.Handle() == KLocalMessageHandle)
       
  1106 			((TPtr8* )aTrg)->Append(buf);
       
  1107 		else
       
  1108 			aMessage.WriteL(0,buf,pos);
       
  1109 		
       
  1110 		pos+=ret;
       
  1111 		if (((TInt)ret)<readTotal)
       
  1112 			break;
       
  1113 		aLength-=readTotal;
       
  1114 		}
       
  1115 	
       
  1116 	if (!CloseHandle(hFile))
       
  1117 		User::Leave(Emulator::LastError());
       
  1118 	}
       
  1119 
       
  1120 //-------------------------------------------------------------------------------------------------------------------
       
  1121 
       
  1122 /**
       
  1123     CLocalMountCB control method.
       
  1124     @param  aLevel  specifies the operation to perfrom on the mount
       
  1125     @param  aOption specific option for the given operation
       
  1126     @param  aParam  pointer to generic parameter, its meaning depends on aLevel and aOption
       
  1127 
       
  1128     @return standard error code.
       
  1129 */
       
  1130 
       
  1131 TInt CLocalMountCB::MountControl(TInt aLevel, TInt aOption, TAny* aParam)
       
  1132     {
       
  1133     //-- File System - specific queries 
       
  1134     if(aLevel == EMountFsParamQuery && aOption == ESQ_GetMaxSupportedFileSize)
       
  1135         {//-- this is a query to provide the max. supported file size; aParam is a pointer to TUint64 to return the value
       
  1136         *(TUint64*)aParam = MaxFileSizeSupported();    
       
  1137         return KErrNone;
       
  1138         }
       
  1139 
       
  1140     return KErrNotSupported; 
       
  1141     }
       
  1142 
       
  1143 //#########################################################################################################################
       
  1144 //##        CLocalFileCB class implementation
       
  1145 //#########################################################################################################################
       
  1146 
       
  1147 
       
  1148 CLocalFileCB::CLocalFileCB()
       
  1149 	{
       
  1150 	}
       
  1151 
       
  1152 CLocalFileCB::~CLocalFileCB()
       
  1153 	{
       
  1154 
       
  1155 	if (iAtt&KEntryAttModified)
       
  1156 		{
       
  1157 		TRAPD(ret,FlushDataL());
       
  1158 //		if (ret!=KErrNone) // Can fail if floppy disk is removed
       
  1159 //			Panic(EFileClose); // Ignore error
       
  1160 		}
       
  1161 	if (iWinHandle!=NULL && !CloseHandle(iWinHandle))
       
  1162 		Panic(EFileClose);
       
  1163 	}
       
  1164 
       
  1165 //-------------------------------------------------------------------------------------------------------------------	
       
  1166 //
       
  1167 // Returns ETrue if the drive number == EDriveZ
       
  1168 //
       
  1169 TBool CLocalFileCB::IsRomDrive() const
       
  1170 	{
       
  1171 
       
  1172 	// WINS emulated rom drive is Z:
       
  1173 	return(((CLocalFileCB*)this)->Mount().Drive().DriveNumber()==EDriveZ);
       
  1174 	}
       
  1175 
       
  1176 //-------------------------------------------------------------------------------------------------------------------	
       
  1177 //
       
  1178 //	Check that the file pointer iCurrentPos is positioned correctly
       
  1179 //	in relation to the Win32 file pointer
       
  1180 //
       
  1181 void CLocalFileCB::CheckPosL(TInt64 aPos)
       
  1182 	{
       
  1183 //	Get the current Win32 file pointer position	
       
  1184 	LARGE_INTEGER pos;
       
  1185 	pos.QuadPart = 0;
       
  1186 	DWORD position=SetFilePointer(iWinHandle,pos.LowPart,&pos.HighPart,FILE_CURRENT);
       
  1187 	TInt r = Emulator::LastError();
       
  1188 	if ((KInvalidSetFilePointer == position) && (r != NO_ERROR))
       
  1189 		User::Leave(r);
       
  1190 //	Set iCurrentPos and Win32 file pointers to aPos if they are different to each
       
  1191 //	other or different to aPos
       
  1192 	if ((pos.QuadPart!=iCurrentPos) || (iCurrentPos!=aPos))
       
  1193 		{
       
  1194 		iCurrentPos=(-1);
       
  1195 		pos.QuadPart = aPos;
       
  1196 		position = SetFilePointer(iWinHandle,pos.LowPart,&pos.HighPart,FILE_BEGIN);
       
  1197 		r = Emulator::LastError();
       
  1198 		if ((KInvalidSetFilePointer == position) && (r != NO_ERROR))
       
  1199 			User::Leave(r);
       
  1200 		iCurrentPos=aPos;
       
  1201 		}
       
  1202 	}
       
  1203 
       
  1204 //-------------------------------------------------------------------------------------------------------------------	
       
  1205 void CLocalFileCB::ReadL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
       
  1206 	{
       
  1207 	ReadL((TInt64)aPos, aLength, (TDes8*)aDes, aMessage, 0);
       
  1208 	}
       
  1209 
       
  1210 //-------------------------------------------------------------------------------------------------------------------	
       
  1211 void CLocalFileCB::WriteL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
       
  1212 	{
       
  1213 	WriteL((TInt64)aPos, aLength, (TDesC8*)aDes, aMessage, 0);
       
  1214 	}
       
  1215 
       
  1216 struct SRomMap
       
  1217 	{
       
  1218 	HBufC* iName;
       
  1219 	TUint8* iAddr;
       
  1220 	};
       
  1221 //-------------------------------------------------------------------------------------------------------------------	
       
  1222 
       
  1223 TInt CLocalFileCB::RomAddress(const TDesC& aName, HANDLE aFile, TUint8*& aAddr)
       
  1224 	{
       
  1225 	static CArrayFixSeg<SRomMap>* gRomMap = new CArrayFixSeg<SRomMap>(64);
       
  1226 	for (TInt ii=0; ii<gRomMap->Count(); ii++)
       
  1227 		{
       
  1228 		if (*gRomMap->At(ii).iName == aName)
       
  1229 			{
       
  1230 			aAddr = gRomMap->At(ii).iAddr;
       
  1231 			return KErrNone;
       
  1232 			}
       
  1233 		}
       
  1234 
       
  1235 	HANDLE fileMapping=CreateFileMappingA(aFile,NULL,PAGE_READONLY,0,0,NULL);
       
  1236 	if (fileMapping==0)
       
  1237 		return Emulator::LastError();
       
  1238 	aAddr=(TUint8*)MapViewOfFile(fileMapping,FILE_MAP_READ,0,0,0);
       
  1239 	SRomMap entry;
       
  1240 	entry.iAddr = aAddr;
       
  1241 	entry.iName = aName.Alloc();
       
  1242 	if (entry.iName)
       
  1243 		{
       
  1244 		TRAPD(ignore, gRomMap->AppendL(entry));
       
  1245 		}
       
  1246 	return KErrNone;
       
  1247 	}
       
  1248 
       
  1249 //-------------------------------------------------------------------------------------------------------------------	
       
  1250 //
       
  1251 // If ROM file, do a memory map and return the address
       
  1252 //
       
  1253 TInt CLocalFileCB::Address(TInt& aPos) const
       
  1254 	{
       
  1255 
       
  1256 	TBool isRomFile=IsRomDrive();
       
  1257 	if (!isRomFile)
       
  1258 		return(KErrNotSupported);
       
  1259 	
       
  1260 	if (aPos>Size64())
       
  1261 		return(KErrEof);
       
  1262 	if (iFilePtr==NULL)
       
  1263 		{
       
  1264 		CLocalFileCB* This=(CLocalFileCB*)this;
       
  1265 		TInt err = RomAddress(*iFileName, iWinHandle, This->iFilePtr);
       
  1266 		if (err)
       
  1267 			return err;
       
  1268 		}
       
  1269 	aPos=(TInt)((TUint8*)iFilePtr+aPos);
       
  1270 	return(KErrNone);
       
  1271 	}
       
  1272 
       
  1273 //-------------------------------------------------------------------------------------------------------------------	
       
  1274 //
       
  1275 // Set the file size.
       
  1276 //
       
  1277 void CLocalFileCB::SetSizeL(TInt aSize)
       
  1278 	{
       
  1279 	SetSizeL(aSize);
       
  1280 	}
       
  1281 
       
  1282 //-------------------------------------------------------------------------------------------------------------------	
       
  1283 //
       
  1284 // Set the entry's attributes and modified time.
       
  1285 //
       
  1286 void CLocalFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
       
  1287 	{
       
  1288 
       
  1289 	if (IsRomDrive())
       
  1290 		User::Leave(KErrAccessDenied);
       
  1291 	TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
       
  1292 	if (setAttMask|aClearAttMask)
       
  1293 		{
       
  1294 		iAtt|=setAttMask;
       
  1295 		iAtt&=(~aClearAttMask);
       
  1296 		iAtt|=KEntryAttModified;
       
  1297 		}
       
  1298 	if (aSetAttMask&KEntryAttModified)
       
  1299 		iModified=aTime;
       
  1300 	iAtt|=KEntryAttModified;
       
  1301 	}
       
  1302 
       
  1303 //-------------------------------------------------------------------------------------------------------------------	
       
  1304 //
       
  1305 // Commit any buffered date to the media.
       
  1306 //
       
  1307 void CLocalFileCB::FlushAllL()
       
  1308 	{
       
  1309 	FlushDataL();
       
  1310 	}
       
  1311 
       
  1312 //-------------------------------------------------------------------------------------------------------------------	
       
  1313 //
       
  1314 // Commit any buffered date to the media.
       
  1315 //
       
  1316 void CLocalFileCB::FlushDataL()
       
  1317 	{
       
  1318 
       
  1319 	if (IsRomDrive())
       
  1320 		return;
       
  1321 
       
  1322 	TFileName n;
       
  1323 	TInt driveNumber=Mount().Drive().DriveNumber();
       
  1324 	MapFileNameL(n,driveNumber,FileName());
       
  1325 	
       
  1326     if(!Emulator::SetFileAttributes(StrPtrZL(n),iAtt&KEntryAttMaskSupported))
       
  1327 		User::Leave(Emulator::LastError()); //	Panic(EFileCloseSetAttributes);
       
  1328 	FILETIME f;
       
  1329 	timeToFileTimeL(iModified,&f);
       
  1330 	if (!SetFileTime(iWinHandle,&f,&f,&f))
       
  1331 		User::Leave(Emulator::LastError());
       
  1332 
       
  1333 	iAtt&=(~KEntryAttModified);
       
  1334 	}
       
  1335 
       
  1336 //-------------------------------------------------------------------------------------------------------------------	
       
  1337 //
       
  1338 // Rename the file while open
       
  1339 //
       
  1340 void CLocalFileCB::RenameL(const TDesC& aNewName)
       
  1341 	{
       
  1342 
       
  1343 	TInt driveNumber=Mount().Drive().DriveNumber();
       
  1344 
       
  1345 	TFileName n1;
       
  1346 	MapFileNameL(n1,driveNumber,FileName());
       
  1347 	TFileName n2;
       
  1348 	MapFileNameL(n2,driveNumber,aNewName);
       
  1349 
       
  1350 	CloseHandle(iWinHandle);
       
  1351 	TInt ret=KErrNone;
       
  1352 	if (!Emulator::MoveFile(StrPtrZL(n1),StrPtrZL(n2)))
       
  1353 		{
       
  1354 		ret=Emulator::LastError();
       
  1355 		n2=n1;
       
  1356 		}
       
  1357 	DWORD access=GENERIC_READ|GENERIC_WRITE;
       
  1358 	DWORD share=FILE_SHARE_WRITE|FILE_SHARE_READ;
       
  1359 	DWORD create=OPEN_EXISTING;
       
  1360 	iWinHandle=Emulator::CreateFile(StrPtrZL(n2),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
       
  1361 	if (iWinHandle==INVALID_HANDLE_VALUE)
       
  1362 		User::Leave(Emulator::LastError());
       
  1363 	
       
  1364 	LARGE_INTEGER pos;
       
  1365 	pos.QuadPart = iCurrentPos;
       
  1366 	DWORD position = SetFilePointer(iWinHandle,pos.LowPart,&pos.HighPart,FILE_BEGIN);
       
  1367 	TInt r = Emulator::LastError();
       
  1368 	if ((KInvalidSetFilePointer == position) && (r != NO_ERROR))
       
  1369 		User::Leave(r);	
       
  1370 	
       
  1371 	User::LeaveIfError(ret);
       
  1372 	AllocBufferL(iFileName,aNewName);
       
  1373 	}
       
  1374 
       
  1375 //-------------------------------------------------------------------------------------------------------------------	
       
  1376 TInt CLocalFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
       
  1377 	{
       
  1378 	switch(aInterfaceId)
       
  1379 		{
       
  1380 		case EExtendedFileInterface:
       
  1381 			((CFileCB::MExtendedFileInterface*&) aInterface) = this;
       
  1382 			return KErrNone;
       
  1383 
       
  1384 		default:
       
  1385 			return CFileCB::GetInterface(aInterfaceId,aInterface,aInput);
       
  1386 		}
       
  1387 	}
       
  1388 
       
  1389 //-------------------------------------------------------------------------------------------------------------------	
       
  1390 /**
       
  1391     Read data from the file.
       
  1392     
       
  1393     @param  aFilePos    start read position within a file
       
  1394     @param  aLength     how many bytes to read; on return will be how many bytes actually read
       
  1395     @param  aDes        local buffer desctriptor
       
  1396     @param  aMessage    from file server, used to write data to the buffer in different address space.
       
  1397     @param  aDesOffset  offset within data descriptor where the data will be copied
       
  1398 
       
  1399     @leave on media read error
       
  1400 
       
  1401 */
       
  1402 void CLocalFileCB::ReadL(TInt64 aPos,TInt& aLength,TDes8* aDes,const RMessagePtr2& aMessage, TInt aOffset)
       
  1403 	{
       
  1404 
       
  1405 	const TUint64 KMaxFilePosition = LocalMount().MaxFileSizeSupported()-1;
       
  1406     
       
  1407 
       
  1408     if(KMaxFilePosition < (TUint64)aPos)
       
  1409 		User::Leave(KErrNotSupported);
       
  1410 	
       
  1411 	CheckPosL(aPos);
       
  1412 	TInt pos=0;
       
  1413 	TInt len=aLength;
       
  1414 	TBuf8<0x1000> buf;
       
  1415 
       
  1416 	if (aMessage.Handle() == KLocalMessageHandle)
       
  1417 		((TPtr8* )aDes)->SetLength(0);
       
  1418 
       
  1419 	while (len)
       
  1420 		{
       
  1421 		TInt s=Min(len,buf.MaxLength());
       
  1422 		DWORD res;
       
  1423 		BOOL b=ReadFile(iWinHandle,(TAny*)buf.Ptr(),s,&res,NULL);
       
  1424 		if(!b)
       
  1425 			User::Leave(Emulator::LastError());
       
  1426 
       
  1427 		buf.SetLength(res);
       
  1428 
       
  1429 	if (aMessage.Handle() == KLocalMessageHandle)
       
  1430 		((TPtr8* )aDes)->Append(buf);
       
  1431 	else
       
  1432 		aMessage.WriteL(0,buf,pos + aOffset);
       
  1433 	
       
  1434 		pos+=res;
       
  1435 		if (((TInt)res)<s)
       
  1436 			break;
       
  1437 		len-=s;
       
  1438 		}
       
  1439 	TInt delay = (ReadSpeed * aLength) >> 10;
       
  1440 	if (delay)
       
  1441 		User::AfterHighRes(delay);
       
  1442 	aLength=pos;
       
  1443 	iCurrentPos=aPos+pos;
       
  1444 	}
       
  1445 
       
  1446 //-------------------------------------------------------------------------------------------------------------------	
       
  1447 /**
       
  1448     Write data to the file.
       
  1449     
       
  1450     @param  aFilePos    start write position within a file
       
  1451     @param  aLength     how many bytes to write; on return contain amount of data actually written
       
  1452     @param  aDes        local buffer desctriptor
       
  1453     @param  aMessage    from file server, used to write data to the media from different address space.
       
  1454     @param  aDesOffset  offset within data descriptor 
       
  1455 
       
  1456     @leave on media read error
       
  1457 
       
  1458 */
       
  1459 void CLocalFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aDes,const RMessagePtr2& aMessage, TInt aOffset)
       
  1460 	{
       
  1461 	if (IsRomDrive())
       
  1462 		User::Leave(KErrAccessDenied);
       
  1463 	
       
  1464 	
       
  1465     const TUint64 KMaxFileSize = LocalMount().MaxFileSizeSupported();
       
  1466     const TUint64 KMaxFilePosition = KMaxFileSize - 1;
       
  1467 
       
  1468 	if( KMaxFilePosition < (TUint64)aPos || KMaxFileSize < (TUint64)(aPos + aLength) )
       
  1469 		User::Leave(KErrNotSupported);
       
  1470 	
       
  1471 	CheckPosL(aPos);
       
  1472 	TInt pos=0;
       
  1473 	TInt len=aLength;
       
  1474 	TBuf8<0x1000> buf;
       
  1475 
       
  1476 	while (len)
       
  1477 		{
       
  1478 		TInt s=Min(len,buf.MaxLength());
       
  1479 
       
  1480 		if (aMessage.Handle() == KLocalMessageHandle)
       
  1481 			buf.Copy( ((TPtr8* )aDes)->MidTPtr(pos, s) );
       
  1482 		else
       
  1483 			aMessage.ReadL(0,buf,pos + aOffset);
       
  1484 
       
  1485 		DWORD res;
       
  1486 		BOOL b=WriteFile(iWinHandle,buf.Ptr(),s,&res,NULL);
       
  1487 		
       
  1488         if (!b)
       
  1489 			User::Leave(Emulator::LastError());
       
  1490 
       
  1491 		if (((TInt)res)<s)
       
  1492 			User::Leave(KErrCorrupt);
       
  1493 		
       
  1494         len-=s;
       
  1495 		pos+=s;
       
  1496 		}
       
  1497 	TInt delay = (WriteSpeed * aLength) >> 10;
       
  1498 	if (delay)
       
  1499 		User::AfterHighRes(delay);
       
  1500 	aLength=pos;
       
  1501 	iCurrentPos=aPos+pos;
       
  1502 	}
       
  1503 
       
  1504 //-------------------------------------------------------------------------------------------------------------------	
       
  1505 /**
       
  1506     Set file size.
       
  1507     @param aSize new file size.
       
  1508 */
       
  1509 void CLocalFileCB::SetSizeL(TInt64 aSize)
       
  1510 	{
       
  1511     const TUint64 KMaxFileSize = LocalMount().MaxFileSizeSupported();
       
  1512 
       
  1513 	if(KMaxFileSize < (TUint64)aSize)
       
  1514 		User::Leave(KErrNotSupported);
       
  1515 	
       
  1516 	CheckPosL(aSize);
       
  1517 	if(!SetEndOfFile(iWinHandle))
       
  1518 		{
       
  1519 		iCurrentPos= -1;
       
  1520 		User::Leave(Emulator::LastError());
       
  1521 		}
       
  1522 
       
  1523 	SetSize64(aSize, EFalse);
       
  1524 	}
       
  1525 
       
  1526 //#########################################################################################################################
       
  1527 //##        CLocalDirCB class implementation
       
  1528 //#########################################################################################################################
       
  1529 
       
  1530 CLocalDirCB::CLocalDirCB()
       
  1531 	        :iEntry()
       
  1532 	{
       
  1533 	}
       
  1534 
       
  1535 CLocalDirCB::~CLocalDirCB()
       
  1536 	{
       
  1537 
       
  1538 	if (iWinHandle!=NULL && !FindClose(iWinHandle))
       
  1539 		Panic(EDirClose);
       
  1540 	}
       
  1541 
       
  1542 //-------------------------------------------------------------------------------------------------------------------	
       
  1543 TBool CLocalDirCB::MatchUid()
       
  1544 	{
       
  1545 
       
  1546 	if (iUidType[0]!=TUid::Null() || iUidType[1]!=TUid::Null() || iUidType[2]!=TUid::Null())
       
  1547 		return(ETrue);
       
  1548 	
       
  1549     return(EFalse);
       
  1550 	}
       
  1551 
       
  1552 //-------------------------------------------------------------------------------------------------------------------	
       
  1553 /** @return  ETrue if the aUidTrg matches aUidSuitor */
       
  1554 static TBool CompareUid(const TUidType& aUidTrg, const TUidType& aUidSuitor)
       
  1555 	{
       
  1556 	
       
  1557 	if (aUidTrg[0]!=TUid::Null() && aUidTrg[0]!=aUidSuitor[0])
       
  1558 		return(EFalse);
       
  1559 	if (aUidTrg[1]!=TUid::Null() && aUidTrg[1]!=aUidSuitor[1])
       
  1560 		return(EFalse);
       
  1561 	if (aUidTrg[2]!=TUid::Null() && aUidTrg[2]!=aUidSuitor[2])
       
  1562 		return(EFalse);
       
  1563 	return(ETrue);
       
  1564 	}
       
  1565 
       
  1566 //-------------------------------------------------------------------------------------------------------------------	
       
  1567 /**
       
  1568     Read current entry from the directory and move to the next one.
       
  1569     This function must leave KErrEof when the end of directory is reached
       
  1570 
       
  1571     @param anEntry extracted directory entry
       
  1572     @leave KErrEof when there are no more entries in the directory
       
  1573            system-wide error code on media read fault.
       
  1574 
       
  1575 */
       
  1576 void CLocalDirCB::ReadL(TEntry& anEntry)
       
  1577 	{
       
  1578 
       
  1579 	if (iWinHandle==NULL)
       
  1580 		User::Leave(KErrEof);
       
  1581 
       
  1582 	FOREVER
       
  1583 		{
       
  1584 		if (!iPending)
       
  1585 			{
       
  1586 			WIN32_FIND_DATA info;
       
  1587 			if (!Emulator::FindNextFile(iWinHandle,&info))
       
  1588 				User::Leave(Emulator::LastError());
       
  1589 
       
  1590 			iEntry.iName.Des()=(TText*)(&info.cFileName[0]);
       
  1591 			iEntry.iAtt=info.dwFileAttributes&KEntryAttMaskSupported;
       
  1592 			iEntry.SetFileSize(MAKE_TINT64(info.nFileSizeHigh,info.nFileSizeLow));
       
  1593 			fileTimeToTime(&info.ftLastWriteTime,iEntry.iModified);
       
  1594 			}
       
  1595 		iPending=EFalse;
       
  1596 		anEntry=iEntry;
       
  1597 		if (anEntry.iName==_L(".") || anEntry.iName==_L(".."))
       
  1598 			continue;
       
  1599 		if ((iFullName.NameAndExt()==_L("*.*") || iFullName.NameAndExt()==_L("*") || anEntry.iName.MatchF(iFullName.NameAndExt())!=KErrNotFound) && Mount().MatchEntryAtt(anEntry.iAtt&KEntryAttMaskSupported,iAtt))
       
  1600 			{
       
  1601 			if (MatchUid())
       
  1602 				{
       
  1603 				TParse fileName;
       
  1604 				TBuf<KMaxFileName> driveAndPath=iFullName.DriveAndPath();
       
  1605 				fileName.Set(anEntry.iName,&driveAndPath,NULL);
       
  1606 				(*(CLocalMountCB*)&Mount()).ReadUidL(fileName.FullName(),anEntry);
       
  1607 				if (CompareUid(iUidType,anEntry.iType))
       
  1608 					break;
       
  1609 				}
       
  1610 			else
       
  1611 				break;
       
  1612 			}
       
  1613 		}
       
  1614 	if ((iAtt&KEntryAttAllowUid)==0 || anEntry.iAtt&KEntryAttDir || MatchUid())
       
  1615 		return;
       
  1616 	TParse fileName;
       
  1617 	TBuf<KMaxFileName> driveAndPath=iFullName.DriveAndPath();
       
  1618 	fileName.Set(anEntry.iName,&driveAndPath,NULL);
       
  1619 	(*(CLocalMountCB*)&Mount()).ReadUidL(fileName.FullName(),anEntry);
       
  1620 	}
       
  1621 
       
  1622 //#########################################################################################################################
       
  1623 //##        CLocalFormatCB class implementation
       
  1624 //#########################################################################################################################
       
  1625 
       
  1626 CLocalFormatCB::CLocalFormatCB()
       
  1627 	{
       
  1628 	}
       
  1629 
       
  1630 CLocalFormatCB::~CLocalFormatCB()
       
  1631 	{
       
  1632 	}
       
  1633 
       
  1634 void CLocalFormatCB::DoFormatStepL()
       
  1635 	{
       
  1636 	iCurrentStep=0;
       
  1637 	User::Leave(KErrNotSupported);
       
  1638 	}
       
  1639 
       
  1640 
       
  1641 //#########################################################################################################################
       
  1642 //##        CLocal File System class implementation
       
  1643 //#########################################################################################################################
       
  1644 
       
  1645 extern "C" 
       
  1646 {
       
  1647 //
       
  1648 // Create a new file system
       
  1649 //
       
  1650 EXPORT_C CFileSystem* CreateFileSystem()
       
  1651 	{
       
  1652 	return(new CLocal);
       
  1653 	}
       
  1654 }
       
  1655 
       
  1656 CLocal::CLocal()
       
  1657 	{
       
  1658 	}
       
  1659 
       
  1660 TInt CLocal::Install()
       
  1661 	{
       
  1662 
       
  1663 	SetErrorMode(SEM_FAILCRITICALERRORS);
       
  1664 	EmulatorDiskSpeed(ReadSpeed, WriteSpeed);
       
  1665 	iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KF32BuildVersionNumber);
       
  1666 	_LIT(KWin32Name,"Win32");
       
  1667 	return(SetName(&KWin32Name));
       
  1668 	}
       
  1669 
       
  1670 CMountCB* CLocal::NewMountL() const
       
  1671 //
       
  1672 // Create a new mount control block.
       
  1673 //
       
  1674 	{
       
  1675 
       
  1676 	return(new(ELeave) CLocalMountCB);
       
  1677 	}
       
  1678 
       
  1679 CFileCB* CLocal::NewFileL() const
       
  1680 //
       
  1681 // Create a new file.
       
  1682 //
       
  1683 	{
       
  1684 
       
  1685 	return(new(ELeave) CLocalFileCB);
       
  1686 	}
       
  1687 
       
  1688 CDirCB* CLocal::NewDirL() const
       
  1689 //
       
  1690 // Create a new directory lister.
       
  1691 //
       
  1692 	{
       
  1693 	return(new(ELeave) CLocalDirCB);
       
  1694 	}
       
  1695 
       
  1696 CFormatCB* CLocal::NewFormatL() const
       
  1697 //
       
  1698 // Create a new media formatter.
       
  1699 //
       
  1700 	{
       
  1701 	return(new(ELeave) CLocalFormatCB);
       
  1702 	}
       
  1703 
       
  1704 TInt CLocal::DefaultPath(TDes& aPath) const
       
  1705 //
       
  1706 // Return the initial default path.
       
  1707 //
       
  1708 	{
       
  1709 	aPath=_L("?:\\");
       
  1710 	aPath[0] = (TUint8) RFs::GetSystemDriveChar();
       
  1711 	return(KErrNone);
       
  1712 	}
       
  1713 
       
  1714 void CLocal::DriveInfo(TDriveInfo& anInfo,TInt aDriveNumber) const
       
  1715 //
       
  1716 // Return the drive info. iBatteryState already set.
       
  1717 //
       
  1718 	{
       
  1719 
       
  1720 	anInfo.iMediaAtt=0;
       
  1721 
       
  1722 // Get Fake drive info.
       
  1723 	if (aDriveNumber==EDriveZ)
       
  1724 		{
       
  1725 		anInfo.iType=EMediaRom;
       
  1726 		anInfo.iMediaAtt=KMediaAttWriteProtected;
       
  1727 		anInfo.iDriveAtt=KDriveAttRom|KDriveAttInternal;
       
  1728 		return;
       
  1729 		}
       
  1730 	if (aDriveNumber==EDriveC)
       
  1731 		{
       
  1732 		anInfo.iType=EMediaHardDisk;
       
  1733 		anInfo.iMediaAtt=KMediaAttVariableSize;
       
  1734 		anInfo.iDriveAtt=KDriveAttLocal|KDriveAttInternal;
       
  1735 		return;
       
  1736 		}
       
  1737 	TFileName envValue;
       
  1738 	if (MapDrive(envValue,aDriveNumber))
       
  1739 		{
       
  1740 		anInfo.iType=EMediaHardDisk;
       
  1741 		anInfo.iDriveAtt=KDriveAttLocal|KDriveAttInternal;
       
  1742 		return;		
       
  1743 		}
       
  1744 	anInfo.iType=EMediaNotPresent;
       
  1745 	anInfo.iDriveAtt=0;
       
  1746 	}
       
  1747 
       
  1748 
       
  1749 
       
  1750 
       
  1751 
       
  1752 
       
  1753 
       
  1754 
       
  1755 
       
  1756 
       
  1757 
       
  1758 
       
  1759 
       
  1760 
       
  1761