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(),§orsPerCluster,&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,§ions,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 +