os/kernelhwsrv/userlibandfileserver/fileserver/swins/elocal.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/swins/elocal.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1772 @@
     1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "elocal.h"
    1.20 +#include <emulator.h>
    1.21 +#include <TCHAR.h>
    1.22 +
    1.23 +const TInt KMajorVersionNumber=1;
    1.24 +const TInt KMinorVersionNumber=0;
    1.25 +
    1.26 +const TUint KInvalidSetFilePointer = 0xffffffff;	// INVALID_SET_FILE_POINTER
    1.27 +
    1.28 +#pragma data_seg(".data2")
    1.29 +#ifdef __VC32__
    1.30 +#pragma bss_seg(".data2")
    1.31 +#endif
    1.32 +static TInt ReadSpeed;
    1.33 +static TInt WriteSpeed;
    1.34 +#pragma data_seg()
    1.35 +#ifdef __VC32__
    1.36 +#pragma bss_seg()
    1.37 +#endif
    1.38 +
    1.39 +static void Panic(TPanic aPanic)
    1.40 +	{
    1.41 +	User::Panic(_L("LocalFSys"),aPanic);
    1.42 +	}
    1.43 +
    1.44 +
    1.45 +//
    1.46 +// Map aDrive to a path given by environment variables
    1.47 +//
    1.48 +TBool MapDrive(TDes& aFileName, TInt aDrive)
    1.49 +	{
    1.50 +
    1.51 +	TDriveName root(TDriveUnit(aDrive).Name());
    1.52 +	TFileName path;
    1.53 +	TBuf<3> rootWithSlash(root);
    1.54 +	rootWithSlash.Append('\\');
    1.55 +
    1.56 +	if (MapEmulatedFileName(path, rootWithSlash) == KErrNone)
    1.57 +		{
    1.58 +		aFileName=path.Left(3);	// drive letter, colon and backslash
    1.59 +		return(ETrue);
    1.60 +		}
    1.61 +	aFileName=root;  // no trailing backslash
    1.62 +	return(EFalse);
    1.63 +	}
    1.64 +	
    1.65 +TInt MapFileName(TDes& aFileName, TInt aDrive, const TDesC& aName)
    1.66 +	{
    1.67 +	TFileName n(TDriveUnit(aDrive).Name());
    1.68 +	n.Append(aName);
    1.69 +	return MapEmulatedFileName(aFileName,n);
    1.70 +	}
    1.71 +
    1.72 +void MapFileNameL(TDes& aFileName, TInt aDrive, const TDesC& aName)
    1.73 +	{
    1.74 +	User::LeaveIfError(MapFileName(aFileName,aDrive,aName));
    1.75 +	}
    1.76 +
    1.77 +
    1.78 +/**
    1.79 +Check whether a descriptor has enough space for null-terminating and append a zero terminator if it does.
    1.80 +Supposed to be used for Win32 file operations, taking C-like strings as parameters.
    1.81 +The main purpose is to avoid panics caused by descriptors overflow.
    1.82 +
    1.83 +@param  aDes descriptor to be null-terminated; a file(directory) name presumably.
    1.84 +@return cast to LPCTSTR value of the descriptor, supposed to be the unicode string
    1.85 +@leave  KErrBadName if there is no room for trailing zero 
    1.86 +*/
    1.87 +LPCTSTR StrPtrZL(TDes16& aDes)
    1.88 +    {
    1.89 +    if(aDes.MaxLength() - aDes.Length() < 1)
    1.90 +        User::Leave(KErrBadName);  //-- no room for terminating zero
    1.91 +    
    1.92 +    return (LPCTSTR)aDes.PtrZ();
    1.93 +    }
    1.94 +
    1.95 +
    1.96 +
    1.97 +//
    1.98 +// Converts a TTime structure to a Windows/NT filetime.  Assumes that aTime is a
    1.99 +// UTC (system) time
   1.100 +//
   1.101 +static void timeToFileTimeL(const TTime& aTime,FILETIME* f)
   1.102 +	{
   1.103 +
   1.104 +	TDateTime dateTime=aTime.DateTime();
   1.105 +	SYSTEMTIME t;
   1.106 +	#pragma warning( disable : 4244 ) // conversion from 'const int' to 'unsigned short', possible loss of data
   1.107 +	t.wYear=dateTime.Year();
   1.108 +	t.wMonth=dateTime.Month()+1;
   1.109 +	t.wDay=dateTime.Day()+1;
   1.110 +	t.wDayOfWeek=(aTime.DayNoInWeek()+1)%7;
   1.111 +	t.wHour=dateTime.Hour();
   1.112 +	t.wMinute=dateTime.Minute();
   1.113 +	t.wSecond=dateTime.Second();
   1.114 +	t.wMilliseconds=dateTime.MicroSecond()/1000;
   1.115 +	#pragma warning( default : 4244 ) // conversion from 'const int' to 'unsigned short', possible loss of data
   1.116 +	__ASSERT_ALWAYS(SystemTimeToFileTime(&t,f)==TRUE,User::Leave(KErrArgument));
   1.117 +	}
   1.118 +
   1.119 +//
   1.120 +//	Convert Windows/NT file time to TTime
   1.121 +//	Assumes the NT file time is UTC
   1.122 +//
   1.123 +static void fileTimeToTime(FILETIME* f,TTime& aTime)
   1.124 +	{
   1.125 +	SYSTEMTIME t;
   1.126 +	__ASSERT_ALWAYS(FileTimeToSystemTime(f,&t)==TRUE,Panic(EFileTimeToSystemTime));
   1.127 +	aTime=TDateTime(t.wYear,TMonth(t.wMonth-1),t.wDay-1,t.wHour,t.wMinute,t.wSecond,t.wMilliseconds*1000);
   1.128 +	}
   1.129 +
   1.130 +//
   1.131 +// Return the size and free space on a drive.
   1.132 +//
   1.133 +static TInt GetMediaSize(TInt aDriveNumber,TInt64& aSize,TInt64& aFree)
   1.134 +	{
   1.135 +
   1.136 +	TBuf<4> driveName;
   1.137 +	MapDrive(driveName,aDriveNumber);
   1.138 +	DWORD sectorsPerCluster;
   1.139 +	DWORD bytesPerSector;
   1.140 +	DWORD freeClusters;
   1.141 +	DWORD sizeClusters;
   1.142 +	// this function should be upgraded to GetDiskFreeSpaceEx
   1.143 +	BOOL b=Emulator::GetDiskFreeSpace((LPCTSTR)driveName.PtrZ(),&sectorsPerCluster,&bytesPerSector,&freeClusters,&sizeClusters);
   1.144 +	if (!b)
   1.145 +		return Emulator::LastError();
   1.146 +
   1.147 +	TInt64 bytesPerCluster=(TInt)(sectorsPerCluster*bytesPerSector);
   1.148 +	aSize=TInt64((TInt)sizeClusters)*bytesPerCluster;
   1.149 +	aFree=TInt64((TInt)freeClusters)*bytesPerCluster;
   1.150 +	return(KErrNone);
   1.151 +	}
   1.152 +
   1.153 +//
   1.154 +// Return the volume name and uniqueID.
   1.155 +//
   1.156 +static TInt GetVolumeId(TInt aDriveNumber,TUint& aUniqueID)
   1.157 +	{
   1.158 +
   1.159 +	TBuf<4> driveName;
   1.160 +	MapDrive(driveName,aDriveNumber);
   1.161 +	DWORD uniqueID,componentLength,flags;
   1.162 +	BOOL b=Emulator::GetVolumeInformation((LPCTSTR)driveName.PtrZ(),NULL,0,&uniqueID,&componentLength,&flags,NULL,0);
   1.163 +	if (!b)
   1.164 +		return Emulator::LastError();
   1.165 +
   1.166 +	aUniqueID=uniqueID;
   1.167 +	return(KErrNone);
   1.168 +	}
   1.169 +
   1.170 +//#########################################################################################################################
   1.171 +//##        CLocalMountCB class implementation
   1.172 +//#########################################################################################################################
   1.173 +
   1.174 +
   1.175 +CLocalMountCB::CLocalMountCB()
   1.176 +	{
   1.177 +	}
   1.178 +
   1.179 +CLocalMountCB::~CLocalMountCB()
   1.180 +	{
   1.181 +	}
   1.182 +
   1.183 +
   1.184 +//
   1.185 +// Returns ETrue if the drive == EDriveZ
   1.186 +//
   1.187 +TBool CLocalMountCB::IsRomDrive() const
   1.188 +	{
   1.189 +	// WINS emulated rom drive is Z:
   1.190 +	return(Drive().DriveNumber()==EDriveZ);
   1.191 +	}
   1.192 +
   1.193 +//-------------------------------------------------------------------------------------------------------------------
   1.194 +
   1.195 +/**
   1.196 +Mount a volume. 
   1.197 +
   1.198 +@param aForceMount Flag to indicate whether mount should be forced to succeed if an error occurs
   1.199 +@leave KErrNoMemory,KErrNotReady,KErrCorrupt,KErrUnknown.
   1.200 +*/
   1.201 +void CLocalMountCB::MountL(TBool /*aForceMount*/)
   1.202 +	{
   1.203 +	TInt64 s,f;
   1.204 +	const TInt driveNum=Drive().DriveNumber();
   1.205 +	User::LeaveIfError(GetMediaSize(driveNum,s,f));
   1.206 +	
   1.207 +    iSize=s;
   1.208 +    if (driveNum==EDriveZ)
   1.209 +		iSize=4*1048576;
   1.210 +	
   1.211 +    User::LeaveIfError(GetVolumeId(driveNum,iUniqueID));
   1.212 +	SetVolumeName(HBufC::NewL(0));	// all Win32 volumes are unnamed
   1.213 +	
   1.214 +    //-- assign default value, 4G-1
   1.215 +    iMaxFileSizeSupported = ((TUint64)4 << 30)-1;
   1.216 +
   1.217 +        {
   1.218 +        //-- find out the maximal supported file size. For this we need to query the name of the windows filesystem that is
   1.219 +        //-- used for the emulated drive
   1.220 +        TBuf<20> bufWinDrive;
   1.221 +        MapDrive(bufWinDrive, Drive().DriveNumber());
   1.222 +        ASSERT(bufWinDrive.Length() >= 3);
   1.223 +
   1.224 +        TCHAR rootName[10];
   1.225 +        TCHAR volName[30];
   1.226 +        TCHAR volFSFileName[30];
   1.227 +        DWORD volSerNum;
   1.228 +        DWORD volMaxCompLen;
   1.229 +        DWORD volFsFlags;
   1.230 +        
   1.231 +        memset(rootName, 0, sizeof(rootName));
   1.232 +		//SL: added the cast
   1.233 +        wcsncpy(rootName, (const wchar_t*)bufWinDrive.Ptr(), 3); //- something like "k:\\"
   1.234 +
   1.235 +        BOOL b = GetVolumeInformation(rootName, volName, sizeof(volName)/sizeof(TCHAR), &volSerNum, &volMaxCompLen, &volFsFlags, volFSFileName, sizeof(volFSFileName)/sizeof(TCHAR));
   1.236 +        if(b)
   1.237 +            {
   1.238 +            if(_wcsicmp(volFSFileName, _TEXT("NTFS")) == 0)
   1.239 +                {//-- this is NTFS
   1.240 +                iMaxFileSizeSupported = 0xFFFFFFF0000; //-- max. file size for NTFS
   1.241 +                }
   1.242 +             else
   1.243 +                {//-- theoretically other than FAT & NTFS filesystem are possible.. Figure yourself.
   1.244 +            }   }
   1.245 +        }
   1.246 +
   1.247 +
   1.248 +    }
   1.249 +
   1.250 +//-------------------------------------------------------------------------------------------------------------------
   1.251 +/**
   1.252 +    Try remount this volume. Checks if the volume parameters remained the same as on original MountL() call, and
   1.253 +    if they are, re-initialises the mount. 
   1.254 +    @return KErrNone if the remount was OK
   1.255 +            system-wide error code otherwise
   1.256 +*/
   1.257 +TInt CLocalMountCB::ReMount()
   1.258 +	{
   1.259 +
   1.260 +	TInt d=Drive().DriveNumber();
   1.261 +	TUint uniqueID;
   1.262 +	TInt r=GetVolumeId(d,uniqueID);
   1.263 +	if (r==KErrNone && uniqueID!=iUniqueID)
   1.264 +		r=KErrGeneral;
   1.265 +	return(r);
   1.266 +	}
   1.267 +
   1.268 +//-------------------------------------------------------------------------------------------------------------------
   1.269 +void CLocalMountCB::Dismounted()
   1.270 +	{
   1.271 +    }
   1.272 +
   1.273 +//-------------------------------------------------------------------------------------------------------------------
   1.274 +//
   1.275 +// Return the volume info.
   1.276 +//
   1.277 +void CLocalMountCB::VolumeL(TVolumeInfo& aVolume) const
   1.278 +	{
   1.279 +
   1.280 +	TInt64 s,f;
   1.281 +	TInt driveNum=Drive().DriveNumber();
   1.282 +	User::LeaveIfError(GetMediaSize(driveNum,s,f));
   1.283 +	if (driveNum==EDriveZ)
   1.284 +		aVolume.iFree=0;
   1.285 +	else
   1.286 +		aVolume.iFree=f;
   1.287 +	}
   1.288 +
   1.289 +//-------------------------------------------------------------------------------------------------------------------
   1.290 +//
   1.291 +// Set the volume label. Not supported on Win32 volumes
   1.292 +//
   1.293 +void CLocalMountCB::SetVolumeL(TDes&)
   1.294 +	{
   1.295 +
   1.296 +	User::Leave(IsRomDrive() ? KErrAccessDenied : KErrNotSupported);
   1.297 +	}
   1.298 +
   1.299 +//-------------------------------------------------------------------------------------------------------------------
   1.300 +//
   1.301 +// Return the address of the file if it is in rom
   1.302 +//
   1.303 +void CLocalMountCB::IsFileInRom(const TDesC& aName,TUint8*& aFileStart)
   1.304 +	{
   1.305 +
   1.306 +	aFileStart=NULL;
   1.307 +	if (!IsRomDrive())
   1.308 +		return;
   1.309 +
   1.310 +	TFileName n;
   1.311 +	if (MapFileName(n,Drive().DriveNumber(),aName)!=KErrNone)
   1.312 +		return;
   1.313 +	
   1.314 +	DWORD access=GENERIC_READ;
   1.315 +	DWORD share=FILE_SHARE_WRITE|FILE_SHARE_READ;
   1.316 +	DWORD create=OPEN_EXISTING;
   1.317 +	HANDLE h=Emulator::CreateFile((LPCTSTR)n.PtrZ(),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
   1.318 +	if (h==INVALID_HANDLE_VALUE)
   1.319 +		return;
   1.320 +
   1.321 +	CLocalFileCB::RomAddress(aName, h, aFileStart);
   1.322 +	CloseHandle(h);
   1.323 +	}
   1.324 +
   1.325 +//-------------------------------------------------------------------------------------------------------------------
   1.326 +/**
   1.327 +    Make a directory.
   1.328 +    @param aName full path to the directory to create. Name validity is checked by file server.
   1.329 +*/
   1.330 +void CLocalMountCB::MkDirL(const TDesC& aName)
   1.331 +	{
   1.332 +
   1.333 +	if (IsRomDrive())
   1.334 +		User::Leave(KErrAccessDenied);
   1.335 +	TFileName n;
   1.336 +	MapFileNameL(n,Drive().DriveNumber(),aName);
   1.337 +	BOOL b=Emulator::CreateDirectory(StrPtrZL(n),NULL);
   1.338 +	
   1.339 +	if (b)
   1.340 +		return;
   1.341 +	TInt r=Emulator::LastError();
   1.342 +	if (r!=KErrAlreadyExists)
   1.343 +		User::Leave(r);
   1.344 +	TEntry e;
   1.345 +	EntryL(aName,e);
   1.346 +
   1.347 +	if (e.IsDir())
   1.348 +		User::Leave(KErrAlreadyExists);
   1.349 +	else
   1.350 +		User::Leave(KErrAccessDenied);
   1.351 +	}
   1.352 +
   1.353 +//-------------------------------------------------------------------------------------------------------------------
   1.354 +/**
   1.355 +    Remove a directory.
   1.356 +    @param aName directory name
   1.357 +*/
   1.358 +void CLocalMountCB::RmDirL(const TDesC& aName)
   1.359 +	{
   1.360 +
   1.361 +	if (IsRomDrive())
   1.362 +		User::Leave(KErrAccessDenied);
   1.363 +	
   1.364 +    TFileName n;
   1.365 +	MapFileNameL(n,Drive().DriveNumber(),aName);
   1.366 +	BOOL b=Emulator::RemoveDirectory(StrPtrZL(n));
   1.367 +	
   1.368 +	if (!b)
   1.369 +		User::Leave(Emulator::LastError());
   1.370 +	}
   1.371 +
   1.372 +//-------------------------------------------------------------------------------------------------------------------
   1.373 +//
   1.374 +// Delete a file.
   1.375 +//
   1.376 +void CLocalMountCB::DeleteL(const TDesC& aName)
   1.377 +	{
   1.378 +
   1.379 +	if (IsRomDrive())
   1.380 +		User::Leave(KErrAccessDenied);
   1.381 +	
   1.382 +    //-- check entry attributes
   1.383 +    TEntry entry;
   1.384 +    EntryL(aName, entry);
   1.385 +	if (entry.IsDir() ||  entry.IsReadOnly())
   1.386 +	    User::Leave(KErrAccessDenied);
   1.387 +
   1.388 +    TFileName n;
   1.389 +	MapFileNameL(n,Drive().DriveNumber(),aName);
   1.390 +	BOOL b=Emulator::DeleteFile(StrPtrZL(n));
   1.391 +	
   1.392 +	if (!b)
   1.393 +		User::Leave(Emulator::LastError());
   1.394 +	}
   1.395 +
   1.396 +//-------------------------------------------------------------------------------------------------------------------
   1.397 +//
   1.398 +// Rename a file or directory.
   1.399 +//
   1.400 +void CLocalMountCB::RenameL(const TDesC& aOldName,const TDesC& aNewName)
   1.401 +	{
   1.402 +
   1.403 +	if (IsRomDrive())
   1.404 +		User::Leave(KErrAccessDenied);
   1.405 +	TEntry entry;
   1.406 +	TRAPD(r,EntryL(aNewName,entry));
   1.407 +	if (r!=KErrNone && r!=KErrNotFound)
   1.408 +		User::Leave(r);
   1.409 +	TFileName old;
   1.410 +	MapFileNameL(old,Drive().DriveNumber(),aOldName);
   1.411 +	TFileName n;
   1.412 +	MapFileNameL(n,Drive().DriveNumber(),aNewName);
   1.413 +	BOOL b=Emulator::MoveFile(StrPtrZL(old),StrPtrZL(n));
   1.414 +	
   1.415 +	if (!b)
   1.416 +		User::Leave(Emulator::LastError());
   1.417 +	}
   1.418 +
   1.419 +//-------------------------------------------------------------------------------------------------------------------
   1.420 +void CLocalMountCB::ReplaceL(const TDesC& aOldName,const TDesC& aNewName)
   1.421 +//
   1.422 +// Delete aNewName if it exists and rename anOldName.
   1.423 +//
   1.424 +	{
   1.425 +
   1.426 +	if (IsRomDrive())
   1.427 +		User::Leave(KErrAccessDenied);
   1.428 +	TEntry entry;
   1.429 +	if(FileNamesIdentical(aOldName,aNewName))
   1.430 +		{
   1.431 +		return;
   1.432 +		}
   1.433 +	TRAPD(r,DeleteL(aNewName));
   1.434 +	if (r!=KErrNotFound && r!=KErrNone)
   1.435 +		User::Leave(r);
   1.436 +	TFileName old;
   1.437 +	MapFileNameL(old,Drive().DriveNumber(),aOldName);
   1.438 +	TFileName n;
   1.439 +	MapFileNameL(n,Drive().DriveNumber(),aNewName);
   1.440 +	BOOL b=Emulator::MoveFile(StrPtrZL(old),StrPtrZL(n));
   1.441 +	if (!b)
   1.442 +		User::Leave(Emulator::LastError());
   1.443 +	}
   1.444 +	
   1.445 +//-------------------------------------------------------------------------------------------------------------------
   1.446 +//
   1.447 +//	Set and get file pointer for windows files
   1.448 +//	
   1.449 +static DWORD SetFilePointerL(HANDLE hFile,LONG lDistanceToMove,DWORD dwMoveMethod)
   1.450 +	
   1.451 +	{
   1.452 +	DWORD dwRet;
   1.453 +	
   1.454 +	dwRet=SetFilePointer(hFile,lDistanceToMove,0,dwMoveMethod);
   1.455 +	if (dwRet==KInvalidSetFilePointer)	//	INVALID_HANDLE_VALUE
   1.456 +		User::Leave(Emulator::LastError());
   1.457 +
   1.458 +	return (dwRet);	
   1.459 +	}
   1.460 +
   1.461 +//-------------------------------------------------------------------------------------------------------------------
   1.462 +//
   1.463 +//	Set and get file pointer for windows files
   1.464 +//	
   1.465 +static DWORD SetFilePointer64L(HANDLE hFile, LARGE_INTEGER * lpDistanceToMove, DWORD dwMoveMethod)
   1.466 +	{
   1.467 +
   1.468 +	DWORD dwRet;
   1.469 +	
   1.470 +	dwRet=SetFilePointer(hFile, lpDistanceToMove->LowPart, &(lpDistanceToMove->HighPart), dwMoveMethod);
   1.471 +	
   1.472 +    TInt r = Emulator::LastError();
   1.473 +	if ((KInvalidSetFilePointer==dwRet) && (r != NO_ERROR))	
   1.474 +		User::Leave(r);
   1.475 +
   1.476 +	return (dwRet);	
   1.477 +	}
   1.478 +
   1.479 +//-------------------------------------------------------------------------------------------------------------------
   1.480 +/**
   1.481 +    Read file section without opening this file on a file server side.
   1.482 +    
   1.483 +    @param  aName       file name; all trailing dots from the name will be removed
   1.484 +    @param  aFilePos    start read position within a file
   1.485 +    @param  aLength     how many bytes to read; on return will be how many bytes actually read
   1.486 +    @param  aDes        local buffer desctriptor
   1.487 +    @param  aMessage    from file server, used to write data to the buffer in different address space.
   1.488 +
   1.489 +    @leave on media read error
   1.490 +*/
   1.491 +void CLocalMountCB::ReadSectionL(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
   1.492 +	{
   1.493 +	
   1.494 +	TFileName n;
   1.495 +	MapFileNameL(n,Drive().DriveNumber(),aName);
   1.496 +	
   1.497 +	WIN32_FIND_DATA d;
   1.498 +	HANDLE hFile=Emulator::FindFirstFile(StrPtrZL(n),&d);
   1.499 +	if (hFile==INVALID_HANDLE_VALUE)
   1.500 +		User::Leave(Emulator::LastError());
   1.501 +	FOREVER
   1.502 +		{
   1.503 +		TPtrC fileName((TText*)(&d.cFileName[0]));
   1.504 +		if (fileName!=_L(".") && fileName!=_L(".."))
   1.505 +			break;
   1.506 +		if (!Emulator::FindNextFile(hFile,&d))
   1.507 +			{
   1.508 +			TInt r = Emulator::LastError();
   1.509 +			User::Leave(r == KErrEof ? KErrNotFound : r);
   1.510 +			}
   1.511 +		}
   1.512 +	
   1.513 +	FindClose(hFile);
   1.514 +		
   1.515 +	hFile=Emulator::CreateFile(StrPtrZL(n),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
   1.516 +	if (hFile==INVALID_HANDLE_VALUE)
   1.517 +		return;
   1.518 +
   1.519 +	DWORD dwSizeLow, dwSizeHigh;
   1.520 +	dwSizeLow=GetFileSize(hFile,&dwSizeHigh);
   1.521 +	TInt r = Emulator::LastError();
   1.522 +	if((NO_ERROR != r) && (INVALID_FILE_SIZE == dwSizeLow))
   1.523 +		User::Leave(r);
   1.524 +	
   1.525 +	// ReadSectionL can support only upto 2G as aPos is TInt!
   1.526 +	const TInt64 fileSize = MAKE_TINT64(dwSizeHigh, dwSizeHigh);
   1.527 +	if(fileSize > KMaxTInt)
   1.528 +		{
   1.529 +		if (!CloseHandle(hFile))
   1.530 +			User::Leave(Emulator::LastError());
   1.531 +
   1.532 +		User::Leave(KErrTooBig);
   1.533 +		}
   1.534 +	
   1.535 +//	Check that reading from aPos for aLength lies within the file
   1.536 +//	if aPos is within the file, and aLength is too long, read up to EOF
   1.537 +//	If aPos is beyond the file, return a zero length descriptor
   1.538 +
   1.539 +	if ((TInt)dwSizeLow>=(aPos+aLength))	//	Can read entire length requested from aPos	
   1.540 +		SetFilePointerL(hFile,aPos,FILE_BEGIN);			
   1.541 +	
   1.542 +	else if ((TInt)dwSizeLow>aPos)		//	Can read from aPos but not entire length requested
   1.543 +		{
   1.544 +		SetFilePointerL(hFile,aPos,FILE_BEGIN);
   1.545 +		aLength=dwSizeLow-aPos;
   1.546 +		}	
   1.547 +	else						//	Cannot read from aPos because it lies outside file
   1.548 +		{						//	Close file and leave with KErrEof
   1.549 +		if (!CloseHandle(hFile))
   1.550 +			User::Leave(Emulator::LastError());
   1.551 +
   1.552 +		User::Leave(KErrEof);
   1.553 +		}
   1.554 +
   1.555 +	TBuf8<0x1000> buf;
   1.556 +	TInt pos=0;
   1.557 +
   1.558 +	if (aMessage.Handle() == KLocalMessageHandle)
   1.559 +		((TPtr8* )aTrg)->SetLength(0);
   1.560 +	
   1.561 +	while (aLength)
   1.562 +		{
   1.563 +		TInt readTotal=Min(aLength,buf.MaxLength());
   1.564 +		DWORD ret;
   1.565 +		BOOL b=ReadFile(hFile,(TAny*)buf.Ptr(),readTotal,&ret,NULL);
   1.566 +		if (!b || ((TInt)ret!=readTotal))	
   1.567 +			User::Leave(Emulator::LastError());
   1.568 +		buf.SetLength(ret);
   1.569 +		
   1.570 +		if(aMessage.Handle() == KLocalMessageHandle)
   1.571 +			((TPtr8* )aTrg)->Append(buf);
   1.572 +		else
   1.573 +			aMessage.WriteL(0,buf,pos);
   1.574 +	
   1.575 +		pos+=ret;
   1.576 +		if (((TInt)ret)<readTotal)
   1.577 +			break;
   1.578 +		aLength-=readTotal;
   1.579 +		}
   1.580 +			
   1.581 +	if (!CloseHandle(hFile))
   1.582 +		User::Leave(Emulator::LastError());
   1.583 +	}
   1.584 +
   1.585 +
   1.586 +//-------------------------------------------------------------------------------------------------------------------
   1.587 +//
   1.588 +// Read the entry uid if present
   1.589 +//
   1.590 +void CLocalMountCB::ReadUidL(const TDesC& aName,TEntry& anEntry) const
   1.591 +	{
   1.592 +
   1.593 +//  First check to see if the first sixteen bytes form a valid UID
   1.594 +	TBuf<KMaxFileName + 1> fileName=aName;
   1.595 +	HANDLE hFile=Emulator::CreateFile(StrPtrZL(fileName),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
   1.596 +	if (hFile==INVALID_HANDLE_VALUE)
   1.597 +		return;
   1.598 +	DWORD ret;
   1.599 +	TBuf8<sizeof(TCheckedUid)> checkedUidBuf;
   1.600 +	checkedUidBuf.SetLength(sizeof(TCheckedUid));
   1.601 +	ReadFile(hFile,&checkedUidBuf[0],sizeof(TCheckedUid),&ret,NULL);
   1.602 +	if (ret!=sizeof(TCheckedUid))
   1.603 +		goto close;
   1.604 +	{
   1.605 +	TCheckedUid checkedUid(checkedUidBuf);
   1.606 +	if(checkedUid.UidType()!=TUidType(TUid::Null(),TUid::Null(),TUid::Null()))
   1.607 +		{
   1.608 +		anEntry.iType=checkedUid.UidType();
   1.609 +		goto close;
   1.610 +		}
   1.611 +	}
   1.612 +
   1.613 +//Look at PE file for UID section
   1.614 +		{
   1.615 +		const TInt KPeHeaderAddrAddr=0x3c;
   1.616 +		const TInt KPeHeaderAddrSize=0x01;
   1.617 +		const TInt KNumberOfSectionsOffset=0x06;
   1.618 +		const TInt KNumberOfSectionsSize=0x02;
   1.619 +		const TInt KSectionTableOffset=0xf8;
   1.620 +		const TInt KSectionHeaderSize=0x28;
   1.621 +		const TInt KSectionNameLength=0x08;
   1.622 +		const TInt KPtrToRawDataOffset=0x14;
   1.623 +		const TInt KPtrToRawDataSize=0x04;
   1.624 +		const TText8 peText[4]={'P','E',0,0};
   1.625 +		const TText8 uidText[8]={'.','S','Y','M','B','I','A','N'};
   1.626 +		
   1.627 +	//Read address of start of PE header
   1.628 +		if (SetFilePointer(hFile,KPeHeaderAddrAddr,0,FILE_BEGIN)==KInvalidSetFilePointer)
   1.629 +			goto close;
   1.630 +		TInt peAddr=0;
   1.631 +		ReadFile(hFile,&peAddr,KPeHeaderAddrSize,&ret,NULL);
   1.632 +		if (ret!=KPeHeaderAddrSize)
   1.633 +			goto close;
   1.634 +		
   1.635 +	//Check it really is the start of PE header
   1.636 +		if (SetFilePointer(hFile,peAddr,0,FILE_BEGIN)==KInvalidSetFilePointer)
   1.637 +			goto close;
   1.638 +		TText8 text[4];
   1.639 +		ReadFile(hFile,text,4,&ret,NULL);
   1.640 +		if (*(TInt32*)text!=*(TInt32*)peText)
   1.641 +			goto close;
   1.642 +		
   1.643 +	//Read number of sections
   1.644 +		if (SetFilePointer(hFile,peAddr+KNumberOfSectionsOffset,0,FILE_BEGIN)==KInvalidSetFilePointer)
   1.645 +			goto close;
   1.646 +		TInt sections=0;
   1.647 +		ReadFile(hFile,&sections,KNumberOfSectionsSize,&ret,NULL);
   1.648 +		if (ret!=KNumberOfSectionsSize)
   1.649 +			goto close;
   1.650 +
   1.651 +	//Go through section headers looking for UID section
   1.652 +		if (SetFilePointer(hFile,peAddr+KSectionTableOffset,0,FILE_BEGIN)==KInvalidSetFilePointer)
   1.653 +			goto close;
   1.654 +		TInt i=0;
   1.655 +		for(;i<sections;i++)
   1.656 +			{
   1.657 +			TText8 name[KSectionNameLength];
   1.658 +			ReadFile(hFile,name,KSectionNameLength,&ret,NULL);
   1.659 +			if (ret!=KSectionNameLength)
   1.660 +				goto close;
   1.661 +			if (*(TInt64*)name==*(TInt64*)uidText)
   1.662 +				break;
   1.663 +			if (SetFilePointer(hFile,KSectionHeaderSize-KSectionNameLength,0,FILE_CURRENT)==KInvalidSetFilePointer)
   1.664 +				goto close;
   1.665 +			}
   1.666 +		if (i==sections)
   1.667 +			goto close;
   1.668 +
   1.669 +	//Read RVA/Offset
   1.670 +		if (SetFilePointer(hFile,KPtrToRawDataOffset-KSectionNameLength,0,FILE_CURRENT)==KInvalidSetFilePointer)
   1.671 +			goto close;
   1.672 +		TInt uidOffset;
   1.673 +		ReadFile(hFile,&uidOffset,KPtrToRawDataSize,&ret,NULL);
   1.674 +		if (ret!=KPtrToRawDataSize)
   1.675 +			goto close;
   1.676 +
   1.677 +	//Read UIDs!
   1.678 +		if (SetFilePointer(hFile,uidOffset,0,FILE_BEGIN)==KInvalidSetFilePointer)
   1.679 +			User::Leave(KErrGeneral);
   1.680 +
   1.681 +		TEmulatorImageHeader header;
   1.682 +		ReadFile(hFile,&header,sizeof(header),&ret,NULL);
   1.683 +		if (ret==sizeof(header))
   1.684 +			anEntry.iType=*(TUidType*)&header;
   1.685 +		}
   1.686 +//Close file
   1.687 +close:
   1.688 +	if (!CloseHandle(hFile))
   1.689 +		User::Leave(Emulator::LastError());
   1.690 +	}
   1.691 +
   1.692 +//-------------------------------------------------------------------------------------------------------------------
   1.693 +/**
   1.694 +    Try to find a directory entry by the given name and path. 
   1.695 +    This method _must_ leave if the entry is not found. See the caller.
   1.696 +
   1.697 +    @param  aName   path to the directory object. all trailing dots from the name will be removed.
   1.698 +    @param  anEntry on return will contain the entry data
   1.699 +    
   1.700 +    @leave  KErrPathNotFound if there is no path to the aName
   1.701 +            KErrNotFound     if the entry corresponding to the aName is not found
   1.702 +            system-wide erorr code of media read failure.
   1.703 +*/
   1.704 +void CLocalMountCB::EntryL(const TDesC& aName,TEntry& anEntry) const
   1.705 +	{
   1.706 +
   1.707 +	TFileName n;
   1.708 +	MapFileNameL(n,Drive().DriveNumber(),aName);
   1.709 +	WIN32_FIND_DATA d;
   1.710 +	HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&d);
   1.711 +	if (h==INVALID_HANDLE_VALUE)
   1.712 +		User::Leave(Emulator::LastError());
   1.713 +	FOREVER
   1.714 +		{
   1.715 +		TPtrC fileName((TText*)(&d.cFileName[0]));
   1.716 +		if (fileName!=_L(".") && fileName!=_L(".."))
   1.717 +			break;
   1.718 +		if (!Emulator::FindNextFile(h,&d))
   1.719 +			{
   1.720 +			TInt r = Emulator::LastError();
   1.721 +			User::Leave(r == KErrEof ? KErrNotFound : r);
   1.722 +			}
   1.723 +		}
   1.724 +	FindClose(h);
   1.725 +	anEntry.iName.Des()=(TText*)(&d.cFileName[0]);
   1.726 +	anEntry.iAtt=d.dwFileAttributes&KEntryAttMaskSupported;
   1.727 +	if (IsRomDrive())
   1.728 +		anEntry.iAtt|=KEntryAttReadOnly;
   1.729 +
   1.730 +	anEntry.SetFileSize(MAKE_TINT64(d.nFileSizeHigh,d.nFileSizeLow));
   1.731 +
   1.732 +	fileTimeToTime(&d.ftLastWriteTime,anEntry.iModified);
   1.733 +	ReadUidL(n,anEntry);
   1.734 +	}
   1.735 +
   1.736 +//-------------------------------------------------------------------------------------------------------------------
   1.737 +/**
   1.738 +    Set directory entry details.
   1.739 +    @param  aName           entry name; all trailing dots from the name will be removed
   1.740 +    @param  aTime           entry modification time (and last access as well)
   1.741 +    @param  aSetAttMask     entry attributes OR mask
   1.742 +    @param  aClearAttMask   entry attributes AND mask
   1.743 +
   1.744 +*/
   1.745 +void CLocalMountCB::SetEntryL(const TDesC& aName,const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
   1.746 +	{
   1.747 +
   1.748 +	if (IsRomDrive())
   1.749 +		User::Leave(KErrAccessDenied);
   1.750 +	TFileName n;
   1.751 +	MapFileNameL(n,Drive().DriveNumber(),aName);
   1.752 +	TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
   1.753 +	DWORD att=Emulator::GetFileAttributes(StrPtrZL(n));
   1.754 +	if (att==0xffffffffu)
   1.755 +		User::Leave(Emulator::LastError());
   1.756 +	
   1.757 +    if (setAttMask|aClearAttMask)
   1.758 +		{
   1.759 +		att|=setAttMask;
   1.760 +		att&=(~aClearAttMask);
   1.761 +		if (!Emulator::SetFileAttributes((LPCTSTR)n.Ptr(),att))
   1.762 +			User::Leave(Emulator::LastError());
   1.763 +		}
   1.764 +	
   1.765 +    if (aSetAttMask&KEntryAttModified)
   1.766 +		{
   1.767 +		FILETIME f;
   1.768 +		timeToFileTimeL(aTime,&f);
   1.769 +
   1.770 +		if (att&KEntryAttReadOnly)
   1.771 +			{
   1.772 +			DWORD writeableAtt=att&(~KEntryAttReadOnly);
   1.773 +			if (!Emulator::SetFileAttributes((LPCTSTR)n.Ptr(),writeableAtt))
   1.774 +				User::Leave(Emulator::LastError());
   1.775 +			}
   1.776 +
   1.777 +		HANDLE h;
   1.778 +		if (att&KEntryAttDir)
   1.779 +			{
   1.780 +			h=Emulator::CreateFile((LPCTSTR)n.Ptr(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_DIRECTORY|FILE_FLAG_BACKUP_SEMANTICS, NULL);
   1.781 +			if (h==INVALID_HANDLE_VALUE)
   1.782 +				User::Leave(Emulator::LastError());
   1.783 +			}
   1.784 +		else
   1.785 +			{
   1.786 +			h=Emulator::CreateFile((LPCTSTR)n.Ptr(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
   1.787 +			if (h==INVALID_HANDLE_VALUE)
   1.788 +				User::Leave(Emulator::LastError());
   1.789 +			}
   1.790 +
   1.791 +		if (!SetFileTime(h,NULL,&f,&f))
   1.792 +			{
   1.793 +			TInt error = Emulator::LastError(); 
   1.794 +			CloseHandle(h);
   1.795 +			User::Leave(error);
   1.796 +			}
   1.797 +		
   1.798 +        if (!CloseHandle(h))
   1.799 +			User::Leave(Emulator::LastError());
   1.800 +		
   1.801 +        if ((att&KEntryAttReadOnly) && !Emulator::SetFileAttributes((LPCTSTR)n.Ptr(),att))
   1.802 +			User::Leave(Emulator::LastError());
   1.803 +		}
   1.804 +	}
   1.805 +
   1.806 +//-------------------------------------------------------------------------------------------------------------------
   1.807 +/**
   1.808 +    Open/Create/Replace a file on the current mount.
   1.809 +    
   1.810 +    @param  aName   file name; all trailing dots from the name will be removed
   1.811 +    @param  aMode   File open mode, See TFileMode
   1.812 +    @param  anOpen  specifies action: open, create or replace the file
   1.813 +    @param  aFile   pointer to the CFileCB object to populate
   1.814 +
   1.815 +*/
   1.816 +void CLocalMountCB::FileOpenL(const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB* aFile)
   1.817 +	{
   1.818 +
   1.819 +	if (IsRomDrive() && (anOpen!=EFileOpen || (aMode&EFileWrite)))
   1.820 +		User::Leave(KErrAccessDenied);
   1.821 +	TFileName n;
   1.822 +	MapFileNameL(n,Drive().DriveNumber(),aName);
   1.823 +	
   1.824 +	DWORD access=GENERIC_READ|GENERIC_WRITE;
   1.825 +	DWORD share=FILE_SHARE_WRITE|FILE_SHARE_READ;
   1.826 +	DWORD create=0;
   1.827 +	switch (anOpen)
   1.828 +		{
   1.829 +	    case EFileOpen: create=OPEN_EXISTING; break;
   1.830 +	    case EFileCreate: create=CREATE_NEW; break;
   1.831 +	    case EFileReplace: create=CREATE_ALWAYS; break;
   1.832 +		}
   1.833 +
   1.834 +	HANDLE h=Emulator::CreateFile(StrPtrZL(n),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
   1.835 +	
   1.836 +	if((h==INVALID_HANDLE_VALUE) && !(aMode&EFileWrite))
   1.837 +	{
   1.838 +	// If windows will not allow write access and it was not requested then open for read only
   1.839 +	access=GENERIC_READ;
   1.840 +	h=Emulator::CreateFile(StrPtrZL(n),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
   1.841 +	}
   1.842 +
   1.843 +	if (h==INVALID_HANDLE_VALUE)
   1.844 +		User::Leave(Emulator::LastError());
   1.845 +	CLocalFileCB& file=(*((CLocalFileCB*)aFile));
   1.846 +	file.SetHandle(h);
   1.847 +	
   1.848 +    BY_HANDLE_FILE_INFORMATION info;
   1.849 +	if (!GetFileInformationByHandle(h,&info))
   1.850 +		User::Leave(Emulator::LastError());
   1.851 +	
   1.852 +    const TUint64 fileSize = MAKE_TUINT64(info.nFileSizeHigh, info.nFileSizeLow);
   1.853 +	
   1.854 +    // Check on file size
   1.855 +	if(MaxFileSizeSupported() < fileSize)
   1.856 +		User::Leave(KErrTooBig);
   1.857 +	
   1.858 +    file.SetMaxSupportedSize(MaxFileSizeSupported());
   1.859 +    file.SetSize64(fileSize, EFalse);
   1.860 +	file.SetAtt(info.dwFileAttributes&KEntryAttMaskSupported);
   1.861 +
   1.862 +//	if (IsRomDrive())
   1.863 +//		file.iAtt|=KEntryAttReadOnly;
   1.864 +	TTime tempTime=file.Modified();
   1.865 +	fileTimeToTime(&info.ftLastWriteTime,tempTime);
   1.866 +	file.SetModified(tempTime);
   1.867 +	}
   1.868 +
   1.869 +void AppendAsteriskL(TDes& aDes)
   1.870 +	{
   1.871 +	if (aDes.Length()==aDes.MaxLength())
   1.872 +		User::Leave(KErrBadName);
   1.873 +	aDes.Append('*');
   1.874 +	}
   1.875 +
   1.876 +//-------------------------------------------------------------------------------------------------------------------	
   1.877 +/**
   1.878 +    Open a directory on the current mount.
   1.879 +    
   1.880 +    @param  aName   path to the object in the directory we want to open; all trailing dots from the name will be removed
   1.881 +    @param  aDir    dir. CB to be filled in.
   1.882 +    
   1.883 +    If there is no such a path, this method must leave with KErrPathNotFound
   1.884 +
   1.885 +    @leave  KErrPathNotFound if thereis no such path
   1.886 +    @leave  error code on media read fault
   1.887 +*/
   1.888 +void CLocalMountCB::DirOpenL(const TDesC& aName,CDirCB* aDir)
   1.889 +	{
   1.890 +
   1.891 +	TFileName n;
   1.892 +	TParse parse;
   1.893 +	MapFileNameL(n,Drive().DriveNumber(),aName);
   1.894 +	parse.Set(n,NULL,NULL);
   1.895 +	n=parse.DriveAndPath();
   1.896 +	AppendAsteriskL(n);
   1.897 +	WIN32_FIND_DATA info;
   1.898 +	HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&info);
   1.899 +	if (h==INVALID_HANDLE_VALUE)
   1.900 +		{
   1.901 +		TInt error=Emulator::LastError();
   1.902 +		TParse parser;
   1.903 +		TInt r=parser.Set(n,NULL,NULL);
   1.904 +		if (r!=KErrNone)
   1.905 +			User::Leave(r);
   1.906 +		if (!parser.IsRoot() || Drive().DriveNumber()!=0 || error!=KErrNotFound)
   1.907 +			User::Leave(error);
   1.908 +		h=NULL;
   1.909 +		}
   1.910 +	CLocalDirCB& dir=(*((CLocalDirCB*)aDir));
   1.911 +	dir.SetHandle(h);
   1.912 +	dir.SetPending(ETrue);
   1.913 +	dir.iEntry.iName.Des()=(TText*)(&info.cFileName[0]);
   1.914 +	dir.iEntry.iAtt=info.dwFileAttributes&KEntryAttMaskSupported;
   1.915 +
   1.916 +	const TInt64 fileSize = MAKE_TINT64(info.nFileSizeHigh,info.nFileSizeLow);
   1.917 +	dir.iEntry.SetFileSize(fileSize);
   1.918 +
   1.919 +	n=parse.FullName();
   1.920 +	if (parse.NameAndExt().Length()==0)
   1.921 +		AppendAsteriskL(n);
   1.922 +	dir.SetFullName(n);
   1.923 +	fileTimeToTime(&info.ftLastWriteTime,dir.iEntry.iModified);
   1.924 +	}
   1.925 +
   1.926 +//-------------------------------------------------------------------------------------------------------------------	
   1.927 +//
   1.928 +// Read directly from disk
   1.929 +//
   1.930 +void CLocalMountCB::RawReadL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aDes*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) const
   1.931 +	{
   1.932 +	User::Leave(KErrNotSupported);
   1.933 +	}
   1.934 +
   1.935 +//-------------------------------------------------------------------------------------------------------------------	
   1.936 +//
   1.937 +// Write directly to disk
   1.938 +//
   1.939 +void CLocalMountCB::RawWriteL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aDes*/ ,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/)
   1.940 +	{
   1.941 +	User::Leave(KErrNotSupported);
   1.942 +	}
   1.943 +
   1.944 +//-------------------------------------------------------------------------------------------------------------------	
   1.945 +//
   1.946 +// Get the short name associated with aLongName
   1.947 +//
   1.948 +void CLocalMountCB::GetShortNameL(const TDesC& aLongName,TDes& aShortName)
   1.949 +	{
   1.950 +
   1.951 +	if (IsRomDrive())
   1.952 +		User::Leave(KErrNotSupported);
   1.953 +
   1.954 +	TFileName n;
   1.955 +	MapFileNameL(n,Drive().DriveNumber(),aLongName);
   1.956 +	WIN32_FIND_DATA d;
   1.957 +	HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&d);
   1.958 +	if (h==INVALID_HANDLE_VALUE)
   1.959 +		User::Leave(Emulator::LastError());
   1.960 +	FindClose(h);
   1.961 +    if (d.cAlternateFileName[0])	// we have a dos name too
   1.962 +        aShortName=(TText*)(&d.cAlternateFileName[0]);
   1.963 +	else
   1.964 +		aShortName=(TText*)(&d.cFileName[0]);
   1.965 +	}
   1.966 +
   1.967 +//-------------------------------------------------------------------------------------------------------------------	
   1.968 +//
   1.969 +// Get the short name associated with aLongName
   1.970 +//
   1.971 +void CLocalMountCB::GetLongNameL(const TDesC& aShortName,TDes& aLongName)
   1.972 +	{
   1.973 +
   1.974 +	if (IsRomDrive())
   1.975 +		User::Leave(KErrNotSupported);
   1.976 +
   1.977 +	TFileName n;
   1.978 +	MapFileNameL(n,Drive().DriveNumber(),aShortName);
   1.979 +	WIN32_FIND_DATA d;
   1.980 +	HANDLE h=Emulator::FindFirstFile(StrPtrZL(n),&d);
   1.981 +	if (h==INVALID_HANDLE_VALUE)
   1.982 +		User::Leave(Emulator::LastError());
   1.983 +	FindClose(h);
   1.984 +	aLongName=(TText*)(&d.cFileName[0]);
   1.985 +	}
   1.986 +
   1.987 +//-------------------------------------------------------------------------------------------------------------------	
   1.988 +/**
   1.989 +Reports whether the specified interface is supported - if it is,
   1.990 +the supplied interface object is modified to it
   1.991 +
   1.992 +@param aInterfaceId     The interface of interest
   1.993 +@param aInterface       The interface object
   1.994 +@return                 KErrNone if the interface is supported, otherwise KErrNotFound 
   1.995 +
   1.996 +@see CMountCB::GetInterface()
   1.997 +*/
   1.998 +TInt CLocalMountCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
   1.999 +    {
  1.1000 +	switch(aInterfaceId)
  1.1001 +		{
  1.1002 +		case EFileExtendedInterface:
  1.1003 +			((CMountCB::MFileExtendedInterface*&) aInterface) = this;
  1.1004 +			return KErrNone;
  1.1005 +
  1.1006 +    	case ELocalBufferSupport:
  1.1007 +    		// CLocalMountCB doesn't ever use any extensions?
  1.1008 +	    	// 	- seems to not have any iProxyDrive or LocalDrive() or similar, 
  1.1009 +    		// so we'll just return KErrNone here.
  1.1010 +   			return KErrNone;
  1.1011 +
  1.1012 +		default:
  1.1013 +		    return CMountCB::GetInterface(aInterfaceId,aInterface,aInput);
  1.1014 +		}
  1.1015 +    }
  1.1016 +
  1.1017 +//-------------------------------------------------------------------------------------------------------------------	
  1.1018 +TInt CLocalMountCB::LocalBufferSupport()
  1.1019 +	{
  1.1020 +	TAny* dummyInterface = NULL;
  1.1021 +	TAny* dummyInput = NULL;
  1.1022 +	return GetInterface(ELocalBufferSupport,dummyInterface,dummyInput);
  1.1023 +	}
  1.1024 +
  1.1025 +//-------------------------------------------------------------------------------------------------------------------	
  1.1026 +/**
  1.1027 +    Read file section without opening this file on a file server side.
  1.1028 +    
  1.1029 +    @param  aName       file name; all trailing dots from the name will be removed
  1.1030 +    @param  aFilePos    start read position within a file
  1.1031 +    @param  aLength     how many bytes to read; on return will be how many bytes actually read
  1.1032 +    @param  aDes        local buffer desctriptor
  1.1033 +    @param  aMessage    from file server, used to write data to the buffer in different address space.
  1.1034 +
  1.1035 +    @leave on media read error
  1.1036 +*/
  1.1037 +void CLocalMountCB::ReadSection64L(const TDesC& aName, TInt64 aPos, TAny* aTrg, TInt aLength, const RMessagePtr2& aMessage)
  1.1038 +	{
  1.1039 +	TFileName n;
  1.1040 +	MapFileNameL(n,Drive().DriveNumber(),aName);
  1.1041 +	
  1.1042 +	WIN32_FIND_DATA d;
  1.1043 +	HANDLE hFile=Emulator::FindFirstFile(StrPtrZL(n),&d);
  1.1044 +	if (hFile==INVALID_HANDLE_VALUE)
  1.1045 +		User::Leave(Emulator::LastError());
  1.1046 +	
  1.1047 +	FOREVER
  1.1048 +		{
  1.1049 +		TPtrC fileName((TText*)(&d.cFileName[0]));
  1.1050 +		if (fileName!=_L(".") && fileName!=_L(".."))
  1.1051 +			break;
  1.1052 +		if (!Emulator::FindNextFile(hFile,&d))
  1.1053 +			{
  1.1054 +			TInt r = Emulator::LastError();
  1.1055 +			User::Leave(r == KErrEof ? KErrNotFound : r);
  1.1056 +			}
  1.1057 +		}
  1.1058 +	
  1.1059 +	FindClose(hFile);
  1.1060 +	
  1.1061 +	hFile=Emulator::CreateFile(StrPtrZL(n),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
  1.1062 +	if (hFile==INVALID_HANDLE_VALUE)
  1.1063 +		return;
  1.1064 +
  1.1065 +	DWORD dwSizeLow, dwSizeHigh;
  1.1066 +	dwSizeLow=GetFileSize(hFile,&dwSizeHigh);
  1.1067 +	TInt r = Emulator::LastError();
  1.1068 +	if((NO_ERROR != r) && (INVALID_FILE_SIZE == dwSizeLow))
  1.1069 +		User::Leave(r);
  1.1070 +	
  1.1071 +	// Check on file size 
  1.1072 +	const TInt64 fileSize = MAKE_TINT64(dwSizeHigh, dwSizeLow);
  1.1073 +	if(MaxFileSizeSupported() < (TUint64)fileSize)
  1.1074 +		{
  1.1075 +		if (!CloseHandle(hFile))
  1.1076 +			User::Leave(Emulator::LastError());
  1.1077 +		
  1.1078 +        User::Leave(KErrTooBig);
  1.1079 +		}
  1.1080 +	
  1.1081 +//	Check that reading from aPos for aLength lies within the file
  1.1082 +//	if aPos is within the file, and aLength is too long, read up to EOF
  1.1083 +//	If aPos is beyond the file, return a zero length descriptor
  1.1084 +
  1.1085 +	if (fileSize>=aPos+aLength)	//	Can read entire length requested from aPos	
  1.1086 +		SetFilePointer64L(hFile,(LARGE_INTEGER *)&aPos,FILE_BEGIN);
  1.1087 +	
  1.1088 +	else if (fileSize>aPos)		//	Can read from aPos but not entire length requested
  1.1089 +		{
  1.1090 +		SetFilePointer64L(hFile,(LARGE_INTEGER *)&aPos,FILE_BEGIN);
  1.1091 +		aLength=(TInt)(fileSize-aPos);
  1.1092 +		}	
  1.1093 +	else						//	Cannot read from aPos because it lies outside file
  1.1094 +		{						//	Close file and leave with KErrEof
  1.1095 +		if (!CloseHandle(hFile))
  1.1096 +			User::Leave(Emulator::LastError());
  1.1097 +
  1.1098 +		User::Leave(KErrEof);
  1.1099 +		}
  1.1100 +
  1.1101 +	TBuf8<0x1000> buf;
  1.1102 +	TInt pos=0;
  1.1103 +
  1.1104 +	if (aMessage.Handle() == KLocalMessageHandle)
  1.1105 +		((TPtr8* )aTrg)->SetLength(0);
  1.1106 +	
  1.1107 +	while (aLength)
  1.1108 +		{
  1.1109 +		TInt readTotal=Min(aLength,buf.MaxLength());
  1.1110 +		DWORD ret;
  1.1111 +		BOOL b=ReadFile(hFile,(TAny*)buf.Ptr(),readTotal,&ret,NULL);
  1.1112 +		if (!b || ((TInt)ret!=readTotal))	
  1.1113 +			User::Leave(Emulator::LastError());
  1.1114 +		buf.SetLength(ret);
  1.1115 +		
  1.1116 +		if(aMessage.Handle() == KLocalMessageHandle)
  1.1117 +			((TPtr8* )aTrg)->Append(buf);
  1.1118 +		else
  1.1119 +			aMessage.WriteL(0,buf,pos);
  1.1120 +		
  1.1121 +		pos+=ret;
  1.1122 +		if (((TInt)ret)<readTotal)
  1.1123 +			break;
  1.1124 +		aLength-=readTotal;
  1.1125 +		}
  1.1126 +	
  1.1127 +	if (!CloseHandle(hFile))
  1.1128 +		User::Leave(Emulator::LastError());
  1.1129 +	}
  1.1130 +
  1.1131 +//-------------------------------------------------------------------------------------------------------------------
  1.1132 +
  1.1133 +/**
  1.1134 +    CLocalMountCB control method.
  1.1135 +    @param  aLevel  specifies the operation to perfrom on the mount
  1.1136 +    @param  aOption specific option for the given operation
  1.1137 +    @param  aParam  pointer to generic parameter, its meaning depends on aLevel and aOption
  1.1138 +
  1.1139 +    @return standard error code.
  1.1140 +*/
  1.1141 +
  1.1142 +TInt CLocalMountCB::MountControl(TInt aLevel, TInt aOption, TAny* aParam)
  1.1143 +    {
  1.1144 +    //-- File System - specific queries 
  1.1145 +    if(aLevel == EMountFsParamQuery && aOption == ESQ_GetMaxSupportedFileSize)
  1.1146 +        {//-- this is a query to provide the max. supported file size; aParam is a pointer to TUint64 to return the value
  1.1147 +        *(TUint64*)aParam = MaxFileSizeSupported();    
  1.1148 +        return KErrNone;
  1.1149 +        }
  1.1150 +
  1.1151 +    return KErrNotSupported; 
  1.1152 +    }
  1.1153 +
  1.1154 +//#########################################################################################################################
  1.1155 +//##        CLocalFileCB class implementation
  1.1156 +//#########################################################################################################################
  1.1157 +
  1.1158 +
  1.1159 +CLocalFileCB::CLocalFileCB()
  1.1160 +	{
  1.1161 +	}
  1.1162 +
  1.1163 +CLocalFileCB::~CLocalFileCB()
  1.1164 +	{
  1.1165 +
  1.1166 +	if (iAtt&KEntryAttModified)
  1.1167 +		{
  1.1168 +		TRAPD(ret,FlushDataL());
  1.1169 +//		if (ret!=KErrNone) // Can fail if floppy disk is removed
  1.1170 +//			Panic(EFileClose); // Ignore error
  1.1171 +		}
  1.1172 +	if (iWinHandle!=NULL && !CloseHandle(iWinHandle))
  1.1173 +		Panic(EFileClose);
  1.1174 +	}
  1.1175 +
  1.1176 +//-------------------------------------------------------------------------------------------------------------------	
  1.1177 +//
  1.1178 +// Returns ETrue if the drive number == EDriveZ
  1.1179 +//
  1.1180 +TBool CLocalFileCB::IsRomDrive() const
  1.1181 +	{
  1.1182 +
  1.1183 +	// WINS emulated rom drive is Z:
  1.1184 +	return(((CLocalFileCB*)this)->Mount().Drive().DriveNumber()==EDriveZ);
  1.1185 +	}
  1.1186 +
  1.1187 +//-------------------------------------------------------------------------------------------------------------------	
  1.1188 +//
  1.1189 +//	Check that the file pointer iCurrentPos is positioned correctly
  1.1190 +//	in relation to the Win32 file pointer
  1.1191 +//
  1.1192 +void CLocalFileCB::CheckPosL(TInt64 aPos)
  1.1193 +	{
  1.1194 +//	Get the current Win32 file pointer position	
  1.1195 +	LARGE_INTEGER pos;
  1.1196 +	pos.QuadPart = 0;
  1.1197 +	DWORD position=SetFilePointer(iWinHandle,pos.LowPart,&pos.HighPart,FILE_CURRENT);
  1.1198 +	TInt r = Emulator::LastError();
  1.1199 +	if ((KInvalidSetFilePointer == position) && (r != NO_ERROR))
  1.1200 +		User::Leave(r);
  1.1201 +//	Set iCurrentPos and Win32 file pointers to aPos if they are different to each
  1.1202 +//	other or different to aPos
  1.1203 +	if ((pos.QuadPart!=iCurrentPos) || (iCurrentPos!=aPos))
  1.1204 +		{
  1.1205 +		iCurrentPos=(-1);
  1.1206 +		pos.QuadPart = aPos;
  1.1207 +		position = SetFilePointer(iWinHandle,pos.LowPart,&pos.HighPart,FILE_BEGIN);
  1.1208 +		r = Emulator::LastError();
  1.1209 +		if ((KInvalidSetFilePointer == position) && (r != NO_ERROR))
  1.1210 +			User::Leave(r);
  1.1211 +		iCurrentPos=aPos;
  1.1212 +		}
  1.1213 +	}
  1.1214 +
  1.1215 +//-------------------------------------------------------------------------------------------------------------------	
  1.1216 +void CLocalFileCB::ReadL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
  1.1217 +	{
  1.1218 +	ReadL((TInt64)aPos, aLength, (TDes8*)aDes, aMessage, 0);
  1.1219 +	}
  1.1220 +
  1.1221 +//-------------------------------------------------------------------------------------------------------------------	
  1.1222 +void CLocalFileCB::WriteL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
  1.1223 +	{
  1.1224 +	WriteL((TInt64)aPos, aLength, (TDesC8*)aDes, aMessage, 0);
  1.1225 +	}
  1.1226 +
  1.1227 +struct SRomMap
  1.1228 +	{
  1.1229 +	HBufC* iName;
  1.1230 +	TUint8* iAddr;
  1.1231 +	};
  1.1232 +//-------------------------------------------------------------------------------------------------------------------	
  1.1233 +
  1.1234 +TInt CLocalFileCB::RomAddress(const TDesC& aName, HANDLE aFile, TUint8*& aAddr)
  1.1235 +	{
  1.1236 +	static CArrayFixSeg<SRomMap>* gRomMap = new CArrayFixSeg<SRomMap>(64);
  1.1237 +	for (TInt ii=0; ii<gRomMap->Count(); ii++)
  1.1238 +		{
  1.1239 +		if (*gRomMap->At(ii).iName == aName)
  1.1240 +			{
  1.1241 +			aAddr = gRomMap->At(ii).iAddr;
  1.1242 +			return KErrNone;
  1.1243 +			}
  1.1244 +		}
  1.1245 +
  1.1246 +	HANDLE fileMapping=CreateFileMappingA(aFile,NULL,PAGE_READONLY,0,0,NULL);
  1.1247 +	if (fileMapping==0)
  1.1248 +		return Emulator::LastError();
  1.1249 +	aAddr=(TUint8*)MapViewOfFile(fileMapping,FILE_MAP_READ,0,0,0);
  1.1250 +	SRomMap entry;
  1.1251 +	entry.iAddr = aAddr;
  1.1252 +	entry.iName = aName.Alloc();
  1.1253 +	if (entry.iName)
  1.1254 +		{
  1.1255 +		TRAPD(ignore, gRomMap->AppendL(entry));
  1.1256 +		}
  1.1257 +	return KErrNone;
  1.1258 +	}
  1.1259 +
  1.1260 +//-------------------------------------------------------------------------------------------------------------------	
  1.1261 +//
  1.1262 +// If ROM file, do a memory map and return the address
  1.1263 +//
  1.1264 +TInt CLocalFileCB::Address(TInt& aPos) const
  1.1265 +	{
  1.1266 +
  1.1267 +	TBool isRomFile=IsRomDrive();
  1.1268 +	if (!isRomFile)
  1.1269 +		return(KErrNotSupported);
  1.1270 +	
  1.1271 +	if (aPos>Size64())
  1.1272 +		return(KErrEof);
  1.1273 +	if (iFilePtr==NULL)
  1.1274 +		{
  1.1275 +		CLocalFileCB* This=(CLocalFileCB*)this;
  1.1276 +		TInt err = RomAddress(*iFileName, iWinHandle, This->iFilePtr);
  1.1277 +		if (err)
  1.1278 +			return err;
  1.1279 +		}
  1.1280 +	aPos=(TInt)((TUint8*)iFilePtr+aPos);
  1.1281 +	return(KErrNone);
  1.1282 +	}
  1.1283 +
  1.1284 +//-------------------------------------------------------------------------------------------------------------------	
  1.1285 +//
  1.1286 +// Set the file size.
  1.1287 +//
  1.1288 +void CLocalFileCB::SetSizeL(TInt aSize)
  1.1289 +	{
  1.1290 +	SetSizeL(aSize);
  1.1291 +	}
  1.1292 +
  1.1293 +//-------------------------------------------------------------------------------------------------------------------	
  1.1294 +//
  1.1295 +// Set the entry's attributes and modified time.
  1.1296 +//
  1.1297 +void CLocalFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
  1.1298 +	{
  1.1299 +
  1.1300 +	if (IsRomDrive())
  1.1301 +		User::Leave(KErrAccessDenied);
  1.1302 +	TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
  1.1303 +	if (setAttMask|aClearAttMask)
  1.1304 +		{
  1.1305 +		iAtt|=setAttMask;
  1.1306 +		iAtt&=(~aClearAttMask);
  1.1307 +		iAtt|=KEntryAttModified;
  1.1308 +		}
  1.1309 +	if (aSetAttMask&KEntryAttModified)
  1.1310 +		iModified=aTime;
  1.1311 +	iAtt|=KEntryAttModified;
  1.1312 +	}
  1.1313 +
  1.1314 +//-------------------------------------------------------------------------------------------------------------------	
  1.1315 +//
  1.1316 +// Commit any buffered date to the media.
  1.1317 +//
  1.1318 +void CLocalFileCB::FlushAllL()
  1.1319 +	{
  1.1320 +	FlushDataL();
  1.1321 +	}
  1.1322 +
  1.1323 +//-------------------------------------------------------------------------------------------------------------------	
  1.1324 +//
  1.1325 +// Commit any buffered date to the media.
  1.1326 +//
  1.1327 +void CLocalFileCB::FlushDataL()
  1.1328 +	{
  1.1329 +
  1.1330 +	if (IsRomDrive())
  1.1331 +		return;
  1.1332 +
  1.1333 +	TFileName n;
  1.1334 +	TInt driveNumber=Mount().Drive().DriveNumber();
  1.1335 +	MapFileNameL(n,driveNumber,FileName());
  1.1336 +	
  1.1337 +    if(!Emulator::SetFileAttributes(StrPtrZL(n),iAtt&KEntryAttMaskSupported))
  1.1338 +		User::Leave(Emulator::LastError()); //	Panic(EFileCloseSetAttributes);
  1.1339 +	FILETIME f;
  1.1340 +	timeToFileTimeL(iModified,&f);
  1.1341 +	if (!SetFileTime(iWinHandle,&f,&f,&f))
  1.1342 +		User::Leave(Emulator::LastError());
  1.1343 +
  1.1344 +	iAtt&=(~KEntryAttModified);
  1.1345 +	}
  1.1346 +
  1.1347 +//-------------------------------------------------------------------------------------------------------------------	
  1.1348 +//
  1.1349 +// Rename the file while open
  1.1350 +//
  1.1351 +void CLocalFileCB::RenameL(const TDesC& aNewName)
  1.1352 +	{
  1.1353 +
  1.1354 +	TInt driveNumber=Mount().Drive().DriveNumber();
  1.1355 +
  1.1356 +	TFileName n1;
  1.1357 +	MapFileNameL(n1,driveNumber,FileName());
  1.1358 +	TFileName n2;
  1.1359 +	MapFileNameL(n2,driveNumber,aNewName);
  1.1360 +
  1.1361 +	CloseHandle(iWinHandle);
  1.1362 +	TInt ret=KErrNone;
  1.1363 +	if (!Emulator::MoveFile(StrPtrZL(n1),StrPtrZL(n2)))
  1.1364 +		{
  1.1365 +		ret=Emulator::LastError();
  1.1366 +		n2=n1;
  1.1367 +		}
  1.1368 +	DWORD access=GENERIC_READ|GENERIC_WRITE;
  1.1369 +	DWORD share=FILE_SHARE_WRITE|FILE_SHARE_READ;
  1.1370 +	DWORD create=OPEN_EXISTING;
  1.1371 +	iWinHandle=Emulator::CreateFile(StrPtrZL(n2),access,share,NULL,create,FILE_FLAG_RANDOM_ACCESS,NULL);
  1.1372 +	if (iWinHandle==INVALID_HANDLE_VALUE)
  1.1373 +		User::Leave(Emulator::LastError());
  1.1374 +	
  1.1375 +	LARGE_INTEGER pos;
  1.1376 +	pos.QuadPart = iCurrentPos;
  1.1377 +	DWORD position = SetFilePointer(iWinHandle,pos.LowPart,&pos.HighPart,FILE_BEGIN);
  1.1378 +	TInt r = Emulator::LastError();
  1.1379 +	if ((KInvalidSetFilePointer == position) && (r != NO_ERROR))
  1.1380 +		User::Leave(r);	
  1.1381 +	
  1.1382 +	User::LeaveIfError(ret);
  1.1383 +	AllocBufferL(iFileName,aNewName);
  1.1384 +	}
  1.1385 +
  1.1386 +//-------------------------------------------------------------------------------------------------------------------	
  1.1387 +TInt CLocalFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
  1.1388 +	{
  1.1389 +	switch(aInterfaceId)
  1.1390 +		{
  1.1391 +		case EExtendedFileInterface:
  1.1392 +			((CFileCB::MExtendedFileInterface*&) aInterface) = this;
  1.1393 +			return KErrNone;
  1.1394 +
  1.1395 +		default:
  1.1396 +			return CFileCB::GetInterface(aInterfaceId,aInterface,aInput);
  1.1397 +		}
  1.1398 +	}
  1.1399 +
  1.1400 +//-------------------------------------------------------------------------------------------------------------------	
  1.1401 +/**
  1.1402 +    Read data from the file.
  1.1403 +    
  1.1404 +    @param  aFilePos    start read position within a file
  1.1405 +    @param  aLength     how many bytes to read; on return will be how many bytes actually read
  1.1406 +    @param  aDes        local buffer desctriptor
  1.1407 +    @param  aMessage    from file server, used to write data to the buffer in different address space.
  1.1408 +    @param  aDesOffset  offset within data descriptor where the data will be copied
  1.1409 +
  1.1410 +    @leave on media read error
  1.1411 +
  1.1412 +*/
  1.1413 +void CLocalFileCB::ReadL(TInt64 aPos,TInt& aLength,TDes8* aDes,const RMessagePtr2& aMessage, TInt aOffset)
  1.1414 +	{
  1.1415 +
  1.1416 +	const TUint64 KMaxFilePosition = LocalMount().MaxFileSizeSupported()-1;
  1.1417 +    
  1.1418 +
  1.1419 +    if(KMaxFilePosition < (TUint64)aPos)
  1.1420 +		User::Leave(KErrNotSupported);
  1.1421 +	
  1.1422 +	CheckPosL(aPos);
  1.1423 +	TInt pos=0;
  1.1424 +	TInt len=aLength;
  1.1425 +	TBuf8<65536> buf;
  1.1426 +
  1.1427 +	if (aMessage.Handle() == KLocalMessageHandle)
  1.1428 +		((TPtr8* )aDes)->SetLength(0);
  1.1429 +
  1.1430 +	while (len)
  1.1431 +		{
  1.1432 +		TInt s=Min(len,buf.MaxLength());
  1.1433 +		DWORD res;
  1.1434 +		BOOL b=ReadFile(iWinHandle,(TAny*)buf.Ptr(),s,&res,NULL);
  1.1435 +		if(!b)
  1.1436 +			User::Leave(Emulator::LastError());
  1.1437 +
  1.1438 +		buf.SetLength(res);
  1.1439 +
  1.1440 +	if (aMessage.Handle() == KLocalMessageHandle)
  1.1441 +		((TPtr8* )aDes)->Append(buf);
  1.1442 +	else
  1.1443 +		aMessage.WriteL(0,buf,pos + aOffset);
  1.1444 +	
  1.1445 +		pos+=res;
  1.1446 +		if (((TInt)res)<s)
  1.1447 +			break;
  1.1448 +		len-=s;
  1.1449 +		}
  1.1450 +	TInt delay = (ReadSpeed * aLength) >> 10;
  1.1451 +	if (delay)
  1.1452 +		User::AfterHighRes(delay);
  1.1453 +	aLength=pos;
  1.1454 +	iCurrentPos=aPos+pos;
  1.1455 +	}
  1.1456 +
  1.1457 +//-------------------------------------------------------------------------------------------------------------------	
  1.1458 +/**
  1.1459 +    Write data to the file.
  1.1460 +    
  1.1461 +    @param  aFilePos    start write position within a file
  1.1462 +    @param  aLength     how many bytes to write; on return contain amount of data actually written
  1.1463 +    @param  aDes        local buffer desctriptor
  1.1464 +    @param  aMessage    from file server, used to write data to the media from different address space.
  1.1465 +    @param  aDesOffset  offset within data descriptor 
  1.1466 +
  1.1467 +    @leave on media read error
  1.1468 +
  1.1469 +*/
  1.1470 +void CLocalFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aDes,const RMessagePtr2& aMessage, TInt aOffset)
  1.1471 +	{
  1.1472 +	if (IsRomDrive())
  1.1473 +		User::Leave(KErrAccessDenied);
  1.1474 +	
  1.1475 +	
  1.1476 +    const TUint64 KMaxFileSize = LocalMount().MaxFileSizeSupported();
  1.1477 +    const TUint64 KMaxFilePosition = KMaxFileSize - 1;
  1.1478 +
  1.1479 +	if( KMaxFilePosition < (TUint64)aPos || KMaxFileSize < (TUint64)(aPos + aLength) )
  1.1480 +		User::Leave(KErrNotSupported);
  1.1481 +	
  1.1482 +	CheckPosL(aPos);
  1.1483 +	TInt pos=0;
  1.1484 +	TInt len=aLength;
  1.1485 +	TBuf8<65536> buf;
  1.1486 +
  1.1487 +	while (len)
  1.1488 +		{
  1.1489 +		TInt s=Min(len,buf.MaxLength());
  1.1490 +
  1.1491 +		if (aMessage.Handle() == KLocalMessageHandle)
  1.1492 +			buf.Copy( ((TPtr8* )aDes)->MidTPtr(pos, s) );
  1.1493 +		else
  1.1494 +			aMessage.ReadL(0,buf,pos + aOffset);
  1.1495 +
  1.1496 +		DWORD res;
  1.1497 +		BOOL b=WriteFile(iWinHandle,buf.Ptr(),s,&res,NULL);
  1.1498 +		
  1.1499 +        if (!b)
  1.1500 +			User::Leave(Emulator::LastError());
  1.1501 +
  1.1502 +		if (((TInt)res)<s)
  1.1503 +			User::Leave(KErrCorrupt);
  1.1504 +		
  1.1505 +        len-=s;
  1.1506 +		pos+=s;
  1.1507 +		}
  1.1508 +	TInt delay = (WriteSpeed * aLength) >> 10;
  1.1509 +	if (delay)
  1.1510 +		User::AfterHighRes(delay);
  1.1511 +	aLength=pos;
  1.1512 +	iCurrentPos=aPos+pos;
  1.1513 +	}
  1.1514 +
  1.1515 +//-------------------------------------------------------------------------------------------------------------------	
  1.1516 +/**
  1.1517 +    Set file size.
  1.1518 +    @param aSize new file size.
  1.1519 +*/
  1.1520 +void CLocalFileCB::SetSizeL(TInt64 aSize)
  1.1521 +	{
  1.1522 +    const TUint64 KMaxFileSize = LocalMount().MaxFileSizeSupported();
  1.1523 +
  1.1524 +	if(KMaxFileSize < (TUint64)aSize)
  1.1525 +		User::Leave(KErrNotSupported);
  1.1526 +	
  1.1527 +	CheckPosL(aSize);
  1.1528 +	if(!SetEndOfFile(iWinHandle))
  1.1529 +		{
  1.1530 +		iCurrentPos= -1;
  1.1531 +		User::Leave(Emulator::LastError());
  1.1532 +		}
  1.1533 +
  1.1534 +	SetSize64(aSize, EFalse);
  1.1535 +	}
  1.1536 +
  1.1537 +//#########################################################################################################################
  1.1538 +//##        CLocalDirCB class implementation
  1.1539 +//#########################################################################################################################
  1.1540 +
  1.1541 +CLocalDirCB::CLocalDirCB()
  1.1542 +	        :iEntry()
  1.1543 +	{
  1.1544 +	}
  1.1545 +
  1.1546 +CLocalDirCB::~CLocalDirCB()
  1.1547 +	{
  1.1548 +
  1.1549 +	if (iWinHandle!=NULL && !FindClose(iWinHandle))
  1.1550 +		Panic(EDirClose);
  1.1551 +	}
  1.1552 +
  1.1553 +//-------------------------------------------------------------------------------------------------------------------	
  1.1554 +TBool CLocalDirCB::MatchUid()
  1.1555 +	{
  1.1556 +
  1.1557 +	if (iUidType[0]!=TUid::Null() || iUidType[1]!=TUid::Null() || iUidType[2]!=TUid::Null())
  1.1558 +		return(ETrue);
  1.1559 +	
  1.1560 +    return(EFalse);
  1.1561 +	}
  1.1562 +
  1.1563 +//-------------------------------------------------------------------------------------------------------------------	
  1.1564 +/** @return  ETrue if the aUidTrg matches aUidSuitor */
  1.1565 +static TBool CompareUid(const TUidType& aUidTrg, const TUidType& aUidSuitor)
  1.1566 +	{
  1.1567 +	
  1.1568 +	if (aUidTrg[0]!=TUid::Null() && aUidTrg[0]!=aUidSuitor[0])
  1.1569 +		return(EFalse);
  1.1570 +	if (aUidTrg[1]!=TUid::Null() && aUidTrg[1]!=aUidSuitor[1])
  1.1571 +		return(EFalse);
  1.1572 +	if (aUidTrg[2]!=TUid::Null() && aUidTrg[2]!=aUidSuitor[2])
  1.1573 +		return(EFalse);
  1.1574 +	return(ETrue);
  1.1575 +	}
  1.1576 +
  1.1577 +//-------------------------------------------------------------------------------------------------------------------	
  1.1578 +/**
  1.1579 +    Read current entry from the directory and move to the next one.
  1.1580 +    This function must leave KErrEof when the end of directory is reached
  1.1581 +
  1.1582 +    @param anEntry extracted directory entry
  1.1583 +    @leave KErrEof when there are no more entries in the directory
  1.1584 +           system-wide error code on media read fault.
  1.1585 +
  1.1586 +*/
  1.1587 +void CLocalDirCB::ReadL(TEntry& anEntry)
  1.1588 +	{
  1.1589 +
  1.1590 +	if (iWinHandle==NULL)
  1.1591 +		User::Leave(KErrEof);
  1.1592 +
  1.1593 +	FOREVER
  1.1594 +		{
  1.1595 +		if (!iPending)
  1.1596 +			{
  1.1597 +			WIN32_FIND_DATA info;
  1.1598 +			if (!Emulator::FindNextFile(iWinHandle,&info))
  1.1599 +				User::Leave(Emulator::LastError());
  1.1600 +
  1.1601 +			iEntry.iName.Des()=(TText*)(&info.cFileName[0]);
  1.1602 +			iEntry.iAtt=info.dwFileAttributes&KEntryAttMaskSupported;
  1.1603 +			iEntry.SetFileSize(MAKE_TINT64(info.nFileSizeHigh,info.nFileSizeLow));
  1.1604 +			fileTimeToTime(&info.ftLastWriteTime,iEntry.iModified);
  1.1605 +			}
  1.1606 +		iPending=EFalse;
  1.1607 +		anEntry=iEntry;
  1.1608 +		if (anEntry.iName==_L(".") || anEntry.iName==_L(".."))
  1.1609 +			continue;
  1.1610 +		if ((iFullName.NameAndExt()==_L("*.*") || iFullName.NameAndExt()==_L("*") || anEntry.iName.MatchF(iFullName.NameAndExt())!=KErrNotFound) && Mount().MatchEntryAtt(anEntry.iAtt&KEntryAttMaskSupported,iAtt))
  1.1611 +			{
  1.1612 +			if (MatchUid())
  1.1613 +				{
  1.1614 +				TParse fileName;
  1.1615 +				TBuf<KMaxFileName> driveAndPath=iFullName.DriveAndPath();
  1.1616 +				fileName.Set(anEntry.iName,&driveAndPath,NULL);
  1.1617 +				(*(CLocalMountCB*)&Mount()).ReadUidL(fileName.FullName(),anEntry);
  1.1618 +				if (CompareUid(iUidType,anEntry.iType))
  1.1619 +					break;
  1.1620 +				}
  1.1621 +			else
  1.1622 +				break;
  1.1623 +			}
  1.1624 +		}
  1.1625 +	if ((iAtt&KEntryAttAllowUid)==0 || anEntry.iAtt&KEntryAttDir || MatchUid())
  1.1626 +		return;
  1.1627 +	TParse fileName;
  1.1628 +	TBuf<KMaxFileName> driveAndPath=iFullName.DriveAndPath();
  1.1629 +	fileName.Set(anEntry.iName,&driveAndPath,NULL);
  1.1630 +	(*(CLocalMountCB*)&Mount()).ReadUidL(fileName.FullName(),anEntry);
  1.1631 +	}
  1.1632 +
  1.1633 +//#########################################################################################################################
  1.1634 +//##        CLocalFormatCB class implementation
  1.1635 +//#########################################################################################################################
  1.1636 +
  1.1637 +CLocalFormatCB::CLocalFormatCB()
  1.1638 +	{
  1.1639 +	}
  1.1640 +
  1.1641 +CLocalFormatCB::~CLocalFormatCB()
  1.1642 +	{
  1.1643 +	}
  1.1644 +
  1.1645 +void CLocalFormatCB::DoFormatStepL()
  1.1646 +	{
  1.1647 +	iCurrentStep=0;
  1.1648 +	User::Leave(KErrNotSupported);
  1.1649 +	}
  1.1650 +
  1.1651 +
  1.1652 +//#########################################################################################################################
  1.1653 +//##        CLocal File System class implementation
  1.1654 +//#########################################################################################################################
  1.1655 +
  1.1656 +extern "C" 
  1.1657 +{
  1.1658 +//
  1.1659 +// Create a new file system
  1.1660 +//
  1.1661 +EXPORT_C CFileSystem* CreateFileSystem()
  1.1662 +	{
  1.1663 +	return(new CLocal);
  1.1664 +	}
  1.1665 +}
  1.1666 +
  1.1667 +CLocal::CLocal()
  1.1668 +	{
  1.1669 +	}
  1.1670 +
  1.1671 +TInt CLocal::Install()
  1.1672 +	{
  1.1673 +
  1.1674 +	SetErrorMode(SEM_FAILCRITICALERRORS);
  1.1675 +	EmulatorDiskSpeed(ReadSpeed, WriteSpeed);
  1.1676 +	iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KF32BuildVersionNumber);
  1.1677 +	_LIT(KWin32Name,"Win32");
  1.1678 +	return(SetName(&KWin32Name));
  1.1679 +	}
  1.1680 +
  1.1681 +CMountCB* CLocal::NewMountL() const
  1.1682 +//
  1.1683 +// Create a new mount control block.
  1.1684 +//
  1.1685 +	{
  1.1686 +
  1.1687 +	return(new(ELeave) CLocalMountCB);
  1.1688 +	}
  1.1689 +
  1.1690 +CFileCB* CLocal::NewFileL() const
  1.1691 +//
  1.1692 +// Create a new file.
  1.1693 +//
  1.1694 +	{
  1.1695 +
  1.1696 +	return(new(ELeave) CLocalFileCB);
  1.1697 +	}
  1.1698 +
  1.1699 +CDirCB* CLocal::NewDirL() const
  1.1700 +//
  1.1701 +// Create a new directory lister.
  1.1702 +//
  1.1703 +	{
  1.1704 +	return(new(ELeave) CLocalDirCB);
  1.1705 +	}
  1.1706 +
  1.1707 +CFormatCB* CLocal::NewFormatL() const
  1.1708 +//
  1.1709 +// Create a new media formatter.
  1.1710 +//
  1.1711 +	{
  1.1712 +	return(new(ELeave) CLocalFormatCB);
  1.1713 +	}
  1.1714 +
  1.1715 +TInt CLocal::DefaultPath(TDes& aPath) const
  1.1716 +//
  1.1717 +// Return the initial default path.
  1.1718 +//
  1.1719 +	{
  1.1720 +	aPath=_L("?:\\");
  1.1721 +	aPath[0] = (TUint8) RFs::GetSystemDriveChar();
  1.1722 +	return(KErrNone);
  1.1723 +	}
  1.1724 +
  1.1725 +void CLocal::DriveInfo(TDriveInfo& anInfo,TInt aDriveNumber) const
  1.1726 +//
  1.1727 +// Return the drive info.
  1.1728 +//
  1.1729 +	{
  1.1730 +
  1.1731 +	anInfo.iMediaAtt=0;
  1.1732 +
  1.1733 +// Get Fake drive info.
  1.1734 +	if (aDriveNumber==EDriveZ)
  1.1735 +		{
  1.1736 +		anInfo.iType=EMediaRom;
  1.1737 +		anInfo.iMediaAtt=KMediaAttWriteProtected;
  1.1738 +		anInfo.iDriveAtt=KDriveAttRom|KDriveAttInternal;
  1.1739 +		anInfo.iConnectionBusType=EConnectionBusInternal;
  1.1740 +		return;
  1.1741 +		}
  1.1742 +	if (aDriveNumber==EDriveC)
  1.1743 +		{
  1.1744 +		anInfo.iType=EMediaHardDisk;
  1.1745 +		anInfo.iMediaAtt=KMediaAttVariableSize;
  1.1746 +		anInfo.iDriveAtt=KDriveAttLocal|KDriveAttInternal;
  1.1747 +		anInfo.iConnectionBusType=EConnectionBusInternal;
  1.1748 +		return;
  1.1749 +		}
  1.1750 +	TFileName envValue;
  1.1751 +	if (MapDrive(envValue,aDriveNumber))
  1.1752 +		{
  1.1753 +		anInfo.iType=EMediaHardDisk;
  1.1754 +		anInfo.iDriveAtt=KDriveAttLocal|KDriveAttInternal;
  1.1755 +		anInfo.iConnectionBusType=EConnectionBusInternal;
  1.1756 +		return;		
  1.1757 +		}
  1.1758 +	anInfo.iType=EMediaNotPresent;
  1.1759 +	anInfo.iDriveAtt=0;
  1.1760 +	}
  1.1761 +
  1.1762 +
  1.1763 +
  1.1764 +
  1.1765 +
  1.1766 +
  1.1767 +
  1.1768 +
  1.1769 +
  1.1770 +
  1.1771 +
  1.1772 +
  1.1773 +
  1.1774 +
  1.1775 +