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