Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32\sfile\sf_utl.cpp
//
//
#include "sf_std.h"
#include <hal.h>
#include <collate.h>
const TInt KLog2BufGranularity=4; // 2^5 == 32
TBool ComparePaths(const TDesC& aPath1,const TDesC& aPath2)
//
// Return ETrue if the paths are identical
// To catch case "\\F32.\\GROUP\\" == "\\F32\\GROUP\\"
//
{
TPtrC entry1(NULL,0);
TPtrC entry2(NULL,0);
TInt pos1=0;
TInt pos2=0;
do {
NextInPath(aPath1,entry1,pos1);
NextInPath(aPath2,entry2,pos2);
if (entry1.MatchF(entry2)==KErrNotFound)
return(EFalse);
} while (entry1.Length() && entry2.Length());
return(ETrue);
}
TBool CompareResource(const TDesC & aThePath)
//
//compare function for the Resource path true for match
//
{
TInt pathLen = aThePath.Length();
if(pathLen < KResourceLength)
return EFalse;
//if not word aligned then no less efficient than treating as TUint16
const TUint32 * path32 = reinterpret_cast<const TUint32*>(aThePath.Ptr());
if( (*path32 & 0xFFDFFFFF) != 0x0052005c) // '/R'
return EFalse;
path32++;
if( (*path32 & 0xFFDFFFDF) != 0x00530045) // 'ES'
return EFalse;
path32++;
if( (*path32 & 0xFFDFFFDF) != 0x0055004F) // 'OU'
return EFalse;
path32++;
if( (*path32 & 0xFFDFFFDF) != 0x00430052) // 'RC'
return EFalse;
path32++;
if(pathLen > KResourceLength)
{
if( (*path32 & 0xFFFFFFDF) != 0x005c0045) // 'E/'
return EFalse;
}
else
{
if( (*path32 & 0x0000FFDF) != 0x00000045) // 'E'
return EFalse;
}
return ETrue;
}
TBool CompareSystem(const TDesC & aThePath)
//
//compare function for the system path true for match
//
{
TInt pathLen = aThePath.Length();
if(pathLen < KSystemLength)
return EFalse;
//if not word aligned then no less efficient than treating as TUint16
const TUint32 * path32 = reinterpret_cast<const TUint32*>(aThePath.Ptr());
if( (*path32 & 0xFFDFFFFF) != 0x0053005c) // '/S'
return EFalse;
path32++;
if( (*path32 & 0xFFDFFFDF) != 0x00530059) // 'YS
return EFalse;
if(pathLen == KSystemLength)
return ETrue;
path32++;
if( (*path32 & 0x0000FFFF) != 0x0000005c) // '/'
return EFalse;
return ETrue;
}
TBool ComparePrivate(const TDesC & aThePath)
//
//compare function to compare if private path being accessed true for match
//
{
TInt pathLen = aThePath.Length();
if(pathLen < KPrivateLength)
return EFalse;
const TUint32 * path32 = reinterpret_cast<const TUint32*>(aThePath.Ptr());
if((*path32 & 0xFFDFFFFF) != 0x0050005c) // '/P'
return EFalse;
path32++;
if( (*path32 & 0xFFDFFFDF) != 0x00490052) // 'RI
return EFalse;
path32++;
if( (*path32 & 0xFFDFFFDF) != 0x00410056) // 'VA'
return EFalse;
path32++;
if( (*path32 & 0xFFDFFFDF) != 0x00450054) // 'TE'
return EFalse;
if(pathLen == KPrivateLength)
return ETrue;
path32++;
if( (*path32 & 0x0000FFFF) != 0x0000005c) // '/'
return EFalse;
return ETrue;
}
TBool SIDCheck(CFsRequest* aRequest, const TDesC& aThePath)
//
// Compare the Private/XXXXXXXX/ portion of a path be accessed to make sure it matches the process SID
//
{
if(aThePath.Length() >= KPrivateLengthCheck)
{
TSecureId appUID = aRequest->Message().SecureId();
TBuf<KSIDLength+1> dirName;
dirName.AppendNumFixedWidth(appUID.iId, EHex, 8);
TInt match = dirName.CompareF(aThePath.Mid(KSIDPathOffset,KPrivateLength));
if(match==KErrNone)
return ETrue;
else
return EFalse;
}
return EFalse;
}
#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, const TSecurityPolicy* aROCap, const char* aDiag)
#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, const TSecurityPolicy* aROCap, OnlyCreateWithNull /*aDiag*/)
#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
//
// Compare the parsed path with protected path names path must be parsed b4 using
//
{
if(aRequest->Message().Handle() == KLocalMessageHandle)
return KErrNone;
#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
#ifdef _DEBUG
TBuf8<512> diagmsg;
TInt len = aThePath.Length();
diagmsg.Append((TUint8*)aThePath.Ptr(),len*2);
diagmsg.Collapse();
diagmsg.SetLength(len);
diagmsg.Append(_L(" Used to call: "));
len = User::StringLength((const TUint8*)aDiag);
diagmsg.Append((TUint8*)aDiag, len);
const char* const diagout = (char*)diagmsg.PtrZ();
#else //!_DEBUG
const char* const diagout = aDiag;
#endif //_DEBUG
#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
if(ComparePrivate(aThePath))
{
if(SIDCheck(aRequest, aThePath))
return KErrNone;
else
{
if(aPriCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
return KErrNone;
else
return KErrPermissionDenied;
}
}
else if(CompareSystem(aThePath))
{
if(aSysCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
return KErrNone;
else
return KErrPermissionDenied;
}
else if(CompareResource(aThePath))
{
if(aROCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
return KErrNone;
else
return KErrPermissionDenied;
}
else
return KErrNone;
}
#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, const char* aDiag)
#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, OnlyCreateWithNull /*aDiag*/)
#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
//
// Compare the parsed path with protected path names path must be parsed b4 using
//
{
if(aRequest->Message().Handle() == KLocalMessageHandle)
return KErrNone;
#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
#ifdef _DEBUG
TBuf8<512> diagmsg;
TInt len = aThePath.Length();
diagmsg.Append((TUint8*)aThePath.Ptr(),len*2);
diagmsg.Collapse();
diagmsg.SetLength(len);
diagmsg.Append(_L(" Used to call: "));
len = User::StringLength((const TUint8*)aDiag);
diagmsg.Append((TUint8*)aDiag, len);
const char* const diagout = (char*)diagmsg.PtrZ();
#else //!_DEBUG
const char* const diagout = aDiag;
#endif //_DEBUG
#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
if(ComparePrivate(aThePath))
{
if(SIDCheck(aRequest, aThePath))
return KErrNone;
else
{
if(aPriCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
return KErrNone;
else
return KErrPermissionDenied;
}
}
else if(CompareSystem(aThePath))
{
if(aSysCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
return KErrNone;
else
return KErrPermissionDenied;
}
else
return KErrNone;
}
#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aCap, const char* aDiag, TBool aExactMatchAllowed)
#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aCap, OnlyCreateWithNull /*aDiag*/, TBool aExactMatchAllowed)
#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
//
// Compare the parsed path with protected path names path must be parsed b4 using
//
{
if(aRequest->Message().Handle() == KLocalMessageHandle)
return KErrNone;
#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
#ifdef _DEBUG
TBuf8<512> diagmsg;
TInt len = aThePath.Length();
diagmsg.Append((TUint8*)aThePath.Ptr(),len*2);
diagmsg.Collapse();
diagmsg.SetLength(len);
diagmsg.Append(_L(" Used to call: "));
len = User::StringLength((const TUint8*)aDiag);
diagmsg.Append((TUint8*)aDiag, len);
const char* const diagout = (char*)diagmsg.PtrZ();
#else //!_DEBUG
const char* const diagout = aDiag;
#endif //_DEBUG
#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
if(ComparePrivate(aThePath))
{
if(SIDCheck(aRequest, aThePath))
return KErrNone;
else
{
if(aCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
return KErrNone;
else if (aExactMatchAllowed && aThePath.Length() <= KPrivateLength + 1)
return KErrNone;
else
return KErrPermissionDenied;
}
}
else if(CompareSystem(aThePath))
{
if(aCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
return KErrNone;
else if (aExactMatchAllowed && aThePath.Length() <= KSystemLength + 1)
return KErrNone;
else
return KErrPermissionDenied;
}
else
return KErrNone;
}
void Fault(TFsFault aFault)
//
// Fault the file server.
//
{
__PRINT1(_L("FAULT: TFsFault %d"),aFault);
User::Panic(_L("Fserv fault"),aFault);
}
/**
Get Ptr() from the client and parse it. Allow wild cards.
Then get the drive and if the drive is substed get the real name.
@param aP message parameter number
@param aRequest pointer to the reques object
@param aParse parser
@param aUseSessionPath flag specifying whether the session path is to be
used for parsing or not. Default value is ETrue meaning
that the session path is used while parsing.
@return system-wide error code.
*/
TInt ParseSubst(const TInt aP, CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath)
{
__ASSERT_DEBUG(aRequest->Session(),Fault(EParseSubstSession));
//-- check the length of the name, passed by client.
//-- it shall not be longer than KMaxFileName
TInt nameLen=aRequest->GetDesLength(aP);
if(nameLen < 0 || nameLen > KMaxFileName)
return KErrBadName;
TFileName n;
TRAPD(r, aRequest->ReadL(aP,n));
if(r==KErrNone)
{
if(aUseSessionPath)
r=aParse.Set(n,NULL,&aRequest->Session()->Path());
else
r=aParse.Set(n,NULL,NULL);
}
if (r!=KErrNone)
return(r);
if(!aUseSessionPath && !aParse.DrivePresent())
return(r);
TInt drive;
if ((r=RFs::CharToDrive(aParse.Drive()[0],drive))!=KErrNone)
return(r);
aRequest->SetDrive(&TheDrives[drive]);
if (aRequest->Drive()->Att()&KDriveAttSubsted)
{
if ((aRequest->Drive()->Subst().Length()+aParse.FullName().Length())>(KMaxFileName+3))
return(KErrBadName);
aRequest->SetSubstedDrive(aRequest->Drive());
// and now set aParse with the full path name
n=aRequest->Drive()->Subst().Mid(2);
n+=aParse.FullName().Mid(3);
TFileName n2=aRequest->SubstedDrive()->Subst().Left(2);
r=aParse.Set(n,NULL,&n2);
if(r!=KErrNone)
return(r);
aRequest->SetDrive(&aRequest->Drive()->SubstedDrive());
}
return(KErrNone);
}
TInt ParseSubstPtr0(CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath)
//
// Get Ptr0() from the client and parse it. Allow wild cards.
// Then get the drive and if the drive is substed get the real name.
//
{
return(ParseSubst(KMsgPtr0,aRequest,aParse,aUseSessionPath));
}
TInt ParseNoWildSubstPtr0(CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath)
//
// Get Ptr0() from the client and parse it. Dis-allow wild cards.
// Then get the drive and if the drive is substed get the real name.
//
{
TInt r=ParseSubst(KMsgPtr0,aRequest,aParse,aUseSessionPath);
if (r!=KErrNone)
return(r); // Returns KErrBadName if "/" in the name or length > 256 chars
if (aParse.IsWild()) // No *s or ?s allowed in the file name
return(KErrBadName);
return(KErrNone);
}
TInt ParseNoWildSubstPtr1(CFsRequest* aRequest,TParse& aParse)
//
// Get Ptr0() from the client and parse it. Dis-allow wild cards.
// Then get the drive and if the drive is substed get the real name.
//
{
TInt r=ParseSubst(KMsgPtr1, aRequest, aParse);
if (r!=KErrNone)
return(r); // Returns KErrBadName if "/" in the name or length > 256 chars
if (aParse.IsWild()) // No *s or ?s allowed in the file name
return(KErrBadName);
return(KErrNone);
}
TInt ParseNoWildSubstCheckPathPtr0(CFsRequest* aRequest,TParse& aParse)
//
// Get Ptr0() from the client and parse it.
// Then get the drive and if the drive is substed get the real name.
// Dis-allow wild cards and the root directory
//
{
TInt r=ParseSubst(KMsgPtr0,aRequest,aParse);
if (r!=KErrNone)
return(r);
if (aParse.IsWild() || (aParse.IsRoot() && !aParse.NameOrExtPresent()))
return(KErrBadName);
return(KErrNone);
}
TInt ParseNoWildSubstCheckPathPtr1(CFsRequest* aRequest,TParse& aParse)
//
// Get Ptr1() from the client and parse it.
// Then get the drive and if the drive is substed get the real name.
// Dis-allow wild cards and the root directory
//
{
TInt r=ParseSubst(KMsgPtr1,aRequest,aParse);
if (r!=KErrNone)
return(r);
if (aParse.IsWild() || (aParse.IsRoot() && !aParse.NameOrExtPresent()))
return(KErrBadName);
return(KErrNone);
}
TInt ParseNoWildSubstFileCheckPtr1(CFsRequest* aRequest,TParse& aParse)
//
// Get Ptr0() from the client and parse it.
// Then get the drive and if the drive is substed get the real name.
// Dis-allow wild cards and the root directory
// Finally check that there is a name or extension.
{
TInt r=ParseSubst(KMsgPtr1,aRequest,aParse);
if (r!=KErrNone)
return(r);
if (aParse.IsWild() || (aParse.IsRoot() && !aParse.NameOrExtPresent()))
return(KErrBadName);
if(!aParse.NameOrExtPresent())
return (KErrBadName);
return(KErrNone);
}
TInt ParseNoWildSubstCheckPtr0(CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath)
//
// Get Ptr0() from the client and parse it. Dis-allow wild cards.
// Then get the drive and if the drive is substed get the real name.
// Finally check that there is a name or extension.
//
{
TInt r=ParseNoWildSubstPtr0(aRequest,aParse, aUseSessionPath);
if (r!=KErrNone)
return(r);
if (!aParse.NameOrExtPresent())
return(KErrBadName);
return(KErrNone);
}
TInt ParseNoWildSubstCheckPtr1(CFsRequest* aRequest,TParse& aParse)
//
// Get Ptr1() from the client and parse it. Dis-allow wild cards.
// Then get the drive and if the drive is substed get the real name.
// Finally check that there is a name or extension.
//
{
TInt r=ParseNoWildSubstPtr1(aRequest,aParse);
if (r!=KErrNone)
return(r);
if (!aParse.NameOrExtPresent())
return(KErrBadName);
return(KErrNone);
}
/**
Get Ptr0() from the client and parse it.
@param aRequest pointer to the reques object
@param aParse parser
@return system-wide error code.
*/
TInt ParsePathPtr0(CFsRequest* aRequest,TParse& aParse)
{
//-- check the length of the name, passed by client.
//-- it shall not be longer than KMaxFileName
TInt nameLen=aRequest->GetDesLength(KMsgPtr0);
if(nameLen < 0 || nameLen > KMaxFileName)
return KErrBadName;
TFileName n;
TRAPD(r,aRequest->ReadL(KMsgPtr0,n));
if (r==KErrNone)
r=aParse.SetNoWild(n,NULL,&aRequest->Session()->Path());
if (r!=KErrNone)
return(r);
if (aParse.NameOrExtPresent())
return(KErrBadName);
TInt drive;
if ((r=RFs::CharToDrive(aParse.Drive()[0],drive))!=KErrNone)
return(r);
aRequest->SetDrive(&TheDrives[drive]);
return(KErrNone);
}
TInt ParseNotificationPath(CFsRequest* aRequest, TParse& aParse, TDes& aNotifyPath)
//
// Called by Notify Change extended function when client has submitted a path
// which contains a wildcarded initial character to represent the drive
// This is required when notification over a number of drives is required
//
{
if ((aNotifyPath[0]==KMatchAny)||(aNotifyPath[0]==KMatchOne))
{
// Use the default session drive for now
TFileName sessionDefault=aRequest->Session()->Path();
aNotifyPath[0]=sessionDefault[0];
}
TInt r=aParse.Set(aNotifyPath,NULL,&aRequest->Session()->Path());
if (r!=KErrNone)
return(r);
TInt drive;
if ((r=RFs::CharToDrive(aParse.Drive()[0],drive))!=KErrNone)
return(r);
aRequest->SetDrive(&TheDrives[drive]);
if (aRequest->Drive()->Att()&KDriveAttSubsted)
{
if ((aRequest->Drive()->Subst().Length()+aParse.FullName().Length())>(KMaxFileName+3))
return(KErrBadName);
aRequest->SetSubstedDrive(aRequest->Drive());
// and now set aParse with the full path name
TFileName n=aRequest->Drive()->Subst().Mid(2);
n+=aParse.FullName().Mid(3);
TFileName n2=aRequest->SubstedDrive()->Subst().Left(2);
r=aParse.Set(n,NULL,&n2);
if(r!=KErrNone)
return(r);
aRequest->SetDrive(&aRequest->Drive()->SubstedDrive());
}
if (aParse.IsWild())
return(KErrBadName);
return(KErrNone);
}
CFsObject* SessionObjectFromHandle(TInt aHandle,TInt aUniqueID, CSessionFs* aSession)
//
// Lookup an object from its handle.
//
{
if(aUniqueID==0)
return(aSession->Handles().At(aHandle,ETrue));
else
return(aSession->Handles().At(aHandle,aUniqueID,ETrue));
}
CFileShare* GetShareFromHandle(CSessionFs* aSession, TInt aHandle)
//
// Get the share control block from its handle.
//
{
return((CFileShare*)(SessionObjectFromHandle(aHandle,FileShares->UniqueID(),aSession)));
}
//
// Returns ETrue if aDes only contains spaces or is zero length
//
static TBool IsSpace(const TDesC& aDes)
{
TInt len=aDes.Length();
if (len==0)
return(EFalse);
for (TInt i=0;i<len;i++)
{
TChar txt=aDes[i];
if (!txt.IsSpace())
return(EFalse);
}
return(ETrue);
}
TUint32 CalcNameHash(const TDesC& aName)
{
const TUint32 KNameHashCRCInitialiser=0x12345678;
TUint32 hash=KNameHashCRCInitialiser;
Mem::Crc32(hash, aName.Ptr(), aName.Size());
return hash;
}
TBool TNameChecker::IsIllegal(TText& aChar) const
//
// Checks aChar != any of < > : " / |
// \ is also illegal in a name but will be considered a path delimiter
//
{
switch (aChar)
{
case '<':
case '>':
case ':':
case '"':
case '/':
case '|':
case '\000':
return(ETrue);
default:
break;
}
return(EFalse);
}
TBool TNameChecker::IsIllegalChar(TText& aChar)
//
// Checks aName for illegal components and returns the offending character if any
// No other parsing is performed
//
{
TInt len=iName.Length();
while (len--)
{
if (IsIllegal(iName[len]))// '<', '>', ':', '"', '/', '|' or '\000'?
{
aChar=iName[len];
return(ETrue);
}
}
return(EFalse);
}
TBool TNameChecker::IsIllegalName()
//
// Checks name is not _L(".") or _L("..") and that there are no illegal characters
//
{
TInt pos=iName.LocateReverse(KPathDelimiter)+1;
TPtrC fileName(iName.Ptr()+pos,iName.Length()-pos);
SetName(fileName);
if (iName==_L(".") || iName==_L("..") || IsSpace(iName))
return ETrue;
TInt len=iName.Length();
while (len--)
{
if (IsIllegal(iName[len])) // '<', '>', ':', '"', '/', '|' or '\000'?
return(ETrue);
}
return(EFalse);
}
TBool TNameChecker::IsIllegalName(TText& aChar)
//
// Check name and path are legal - if not, return the offending component
//
{
TInt r=iParse.Set(iName,NULL,NULL);
if (r!=KErrNone)
return(ETrue); // Checks for names > 256 chars etc
SetName(iParse.FullName());
if (IsIllegalPath(aChar))
return(ETrue); // Checks for illegal characters in path
TInt nameStart=iParse.FullName().LocateReverse(KPathDelimiter)+1;
r=(iParse.FullName().Mid(nameStart)).LocateReverse(KPathDelimiter)+1;
TPtrC fileName(iName.Ptr()+r,iName.Length()-r);
SetName(fileName);
if (iName==_L(".") || iName==_L("..") || IsSpace(iName))
{
aChar=iName[0];
return ETrue;
}
return (IsIllegalChar(aChar));
}
const TInt KSpace = ' ';
TBool TNameChecker::IsIllegalPath()
//
// Checks the path does not contain wildcards or directories _L(".") or _L("..") or just spaces
//
{
if (iName.Locate(KMatchOne)!=KErrNotFound || iName.Locate(KMatchAny)!=KErrNotFound)
return(ETrue);
TLex pathLex=iName;
FOREVER
{
pathLex.Inc();
if (pathLex.Remainder().Length()==0)
break;
TInt nextPath=pathLex.Remainder().Locate(KPathDelimiter);
if (nextPath==0) // Reject double backslashes
return(ETrue);
if (nextPath==KErrNotFound)
nextPath=pathLex.Remainder().Length();
pathLex.Mark();
pathLex.Inc(nextPath);
SetName(pathLex.MarkedToken());
if (IsIllegalName())
return(ETrue);
// check for tailing dots
for(TInt i = pathLex.MarkedToken().Length() - 1; i >= 0; --i)
{
if (pathLex.MarkedToken()[i] == KExtDelimiter)
{
return ETrue;
}
else if (pathLex.MarkedToken()[i] == KSpace)
{
continue;
}
else
{
break;
}
}
}
return(EFalse);
}
TBool TNameChecker::IsIllegalPath(TText& aChar)
//
// Checks the path does not contain wildcards or directories _L(".") or _L("..") or just spaces
// Returns the first offending character found (if any)
//
{
if (iName.Locate(KMatchOne)!=KErrNotFound)
{
aChar=KMatchOne;
return (ETrue);
}
if (iName.Locate(KMatchAny)!=KErrNotFound)
{
aChar=KMatchAny;
return (ETrue);
}
TLex pathLex=iName;
TFileName name;
FOREVER
{
pathLex.Inc();
if (pathLex.Remainder().Length()==0)
break;
TInt nextPath=pathLex.Remainder().Locate(KPathDelimiter);
if (nextPath==0) // Reject double backslashes
{
aChar=KPathDelimiter;
return ETrue;
}
if (nextPath==KErrNotFound)
nextPath=pathLex.Remainder().Length();
pathLex.Mark();
pathLex.Inc(nextPath);
name=pathLex.MarkedToken();
// check for tailing dots
for(TInt i = pathLex.MarkedToken().Length() - 1; i >= 0; --i)
{
if (pathLex.MarkedToken()[i] == KExtDelimiter)
{
aChar = KExtDelimiter;
return ETrue;
}
else if (pathLex.MarkedToken()[i] == KSpace)
{
continue;
}
else
{
break;
}
}
TInt pos=name.LocateReverse(KPathDelimiter)+1;
TPtrC fileName(name.Ptr()+pos,name.Length()-pos);
SetName(fileName);
if (iName==_L(".") || iName==_L("..") || IsSpace(iName))
{
aChar=iName[0];
return ETrue;
}
if (IsIllegalChar(aChar))
return(ETrue);
}
return(EFalse);
}
TBool IsIllegalFullName(const TParse& aParse)
{
TPtrC ptr=aParse.Path();
TNameChecker checker(ptr);
if (checker.IsIllegalPath())
return(ETrue); // Checks for illegal characters in path
TInt nameStart=aParse.FullName().LocateReverse(KPathDelimiter)+1;
checker.SetName(aParse.FullName().Mid(nameStart));
if (checker.IsIllegalName())
return(ETrue); // Checks illegal characters such as ></|". and ..
return(EFalse);
}
TBool IsIllegalFullName(const TDesC& aName)
//
// Check name and path are legal
//
{
TParse parser;
TInt r=parser.Set(aName,NULL,NULL);
if (r!=KErrNone)
return(ETrue); // Checks for wild cards, names>256 chars etc
return IsIllegalFullName(parser);
}
TBool PowerOk()
//
// Check the power is OK
//
{
TBool powerGood=EFalse;
TInt r=HAL::Get(HAL::EPowerGood, powerGood);
if (r!=KErrNone)
return EFalse;
return powerGood;
}
void AddResource(CMountCB& aMount)
//
// Decrement resource counters
//
{
__CHECK_DRIVETHREAD(aMount.Drive().DriveNumber());
__ASSERT_DEBUG(aMount.LockStatus()<=0,Fault(ERawDiskBadAccessCount2));
aMount.DecLock();
}
void RemoveResource(CMountCB& aMount)
//
// Increment resource counters
//
{
__ASSERT_DEBUG(aMount.LockStatus()<0,Fault(ERawDiskBadAccessCount1));
aMount.IncLock();
}
void AddDiskAccess(CMountCB& aMount)
//
// Increment resource counters
//
{
aMount.IncLock();
}
void RemoveDiskAccess(CMountCB& aMount)
//
// Decrement resource counters
//
{
aMount.DecLock();
}
EXPORT_C void AllocBufferL(HBufC*& aBuf,const TDesC& aName)
//
// Alloc or ReAlloc buffer
//
{
if (aBuf==NULL)
{
aBuf=aName.AllocL();
return;
}
if (aBuf->Length()<aName.Length())
{
TInt bufGranularity=(1<<KLog2BufGranularity);
TInt size=((aName.Length()+bufGranularity-1)>>KLog2BufGranularity)<<KLog2BufGranularity;
aBuf=aBuf->ReAllocL(size);
}
aBuf->Des()=aName;
}
void NextInPath(const TDesC& aPath,TPtrC& anEntry,TInt& aPos)
//
// Returns the next entry in the path
//
{
anEntry.Set(NULL,0);
if ((aPos+1)>=aPath.Length())
return;
TPtrC path(aPath.Mid(aPos+1)); // Skip delimiter
TInt delimiterPos=path.Locate(KPathDelimiter);
if (delimiterPos==KErrNotFound)
delimiterPos=aPath.Length()-(aPos+1);
if (delimiterPos<=0)
return;
if (path[delimiterPos-1]==KExtDelimiter) // return "F32." as "F32"
anEntry.Set(aPath.Mid(aPos+1,delimiterPos-1));
else
anEntry.Set(aPath.Mid(aPos+1,delimiterPos));
aPos+=delimiterPos+1;
}
TInt MatchUidType(const TUidType &aMatch, const TUidType &aType)
//
// Compare aType against aMatch with KNullUid as a wildcard
//
{
TUid mu=aMatch[2];
TUid tu=aType[2];
if (mu!=KNullUid && tu!=KNullUid && mu!=tu)
return KErrNotSupported;
mu=aMatch[1];
tu=aType[1];
if (mu!=KNullUid && tu!=KNullUid && mu!=tu)
return KErrNotSupported;
mu=aMatch[0];
tu=aType[0];
if (mu!=KNullUid && tu!=KNullUid && mu!=tu)
return KErrNotSupported;
return KErrNone;
}
/**
* Compare sections of filenames according to locale-independent rules as well
* as locale-dependent rules. This is an attempt to get an ordering where
* equivalent names sort together but the overall ordering is culturally
* acceptable. Sadly, the ordering it gives is not consistent, and it is not
* clear how to make it so. Hence this function is deprecated. The correct way
* to do this is to code around it: If you need a sorted array for display that
* you also need to search for equivalent filenames, either use a linear search
* or keep two arrays, one sorted with CompareF, the other with CompareC.
* @deprecated 6.1
*/
EXPORT_C TInt CompareFilenames(const TDesC& aFileName1,const TDesC& aFileName2)
//
// Compare filenames. Case is ignored and names are normalised
// (base+accent is equal to composed character) but spaces
// and punctuation are significant for determining equality.
// Whether two filenames are identical is the same in all
// locales, but the ordering of non-identical filenames is locale-specific.
//
//
{
// Create a non-locale-specific collation method that doesn't ignore spaces and punctuation but folds case.
TCollationMethod method;
method.iFlags = TCollationMethod::EIgnoreNone | TCollationMethod::EFoldCase;
method.iMainTable=NULL;
method.iOverrideTable=NULL;
// Get the non-locale-specific order and return it if the names are equal.
TInt base_order = aFileName1.CompareC(aFileName2,3,&method);
if (base_order == 0)
return base_order;
// Get the locale-specific order and use it unless it is equality, in which case the non-locale-specific order must be used.
TInt locale_order = aFileName1.CompareC(aFileName2);
return locale_order ? locale_order : base_order;
}
void Get8BitDllName(TDes8& aDllName, const TDesC& aFileName)
//
// Convert a 16 bit name to an 8 bit name
// No data loss because UNICODE Dlls are currently restricted to 8 bit names
// No effect in 8 bit builds - just sets aDllName to aFileName
//
{
aDllName.SetLength(aFileName.Length());
aDllName.Copy(aFileName);
}
void Get16BitDllName(TDes& aFileName, const TDesC8& aDllName)
//
// Convert an 8 bit name to a 16 bit name - zero padded automatically
// No effect in 8 bit builds - just sets aFileName to aDllName
//
{
aFileName.SetLength(aDllName.Length());
aFileName.Copy(aDllName);
}
/**
Checks that there is sufficient disk space available to complete a task taking into account reserved space
@param aThreshold amount of required free space, in bytes
@param aRequest
@return KErrNone on success and if there are _strictly_more_ than aThreshold bytes available on the volume (taking into account reserved space)
KErrDiskFull on success and if there isn't enough space
system-wide error code otherwise
*/
TInt CheckDiskSpace(TInt64 aThreshold, CFsRequest* aRequest)
{
const TInt KReservedSpace = aRequest->Drive()->ReservedSpace();
const TInt KDriveNumber = aRequest->Drive()->DriveNumber();
if(KReservedSpace == 0 || KDriveNumber == EDriveZ)
return KErrNone;
//-- if the drive has a reserved space, take it into account
CSessionFs* session=aRequest->Session();
if(!session || !session->ReservedAccess(KDriveNumber))
aThreshold += KReservedSpace;
//-- ask the corresponding file system if there is aThreshold bytes available.
//-- for some reason it's required to be strictly > than aThreshold
return aRequest->Drive()->RequestFreeSpaceOnMount(aThreshold+1);
}
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
EXPORT_C TUint32 DebugRegister() {return(DebugReg);}
#else
EXPORT_C TUint32 DebugRegister() {return(0);}
#endif
CLogon* CLogon::NewL()
//
// Create the CLogon active object.
//
{
CLogon* pL=new(ELeave) CLogon(EPriority);
CActiveScheduler::Add(pL);
return(pL);
}
#pragma warning( disable : 4705 ) // statement has no effect
CLogon::CLogon(TInt aPriority)
//
// Constructor
//
: CActive(aPriority)
{
}
#pragma warning( default : 4705 )
TInt CLogon::Logon(RThread aThread)
//
// Issue a request to logon to the thread.
//
{
iThread=aThread;
iThread.Logon(iStatus);
SetActive();
if (iStatus==KErrNoMemory)
iThread.Kill(KErrNoMemory);
else
iThread.Resume();
iThread.Close();
CActiveScheduler::Start();
return(iStatus.Int());
}
void CLogon::DoCancel()
//
// Cancel a pending event.
//
{
iThread.LogonCancel(iStatus);
}
void CLogon::RunL()
//
// Thread has terminated.
//
{
CActiveScheduler::Stop();
}