1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_utl.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1144 @@
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 +// f32\sfile\sf_utl.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "sf_std.h"
1.22 +#include <hal.h>
1.23 +#include <collate.h>
1.24 +
1.25 +const TInt KLog2BufGranularity=4; // 2^5 == 32
1.26 +
1.27 +TBool ComparePaths(const TDesC& aPath1,const TDesC& aPath2)
1.28 +//
1.29 +// Return ETrue if the paths are identical
1.30 +// To catch case "\\F32.\\GROUP\\" == "\\F32\\GROUP\\"
1.31 +//
1.32 + {
1.33 +
1.34 + TPtrC entry1(NULL,0);
1.35 + TPtrC entry2(NULL,0);
1.36 + TInt pos1=0;
1.37 + TInt pos2=0;
1.38 +
1.39 + do {
1.40 + NextInPath(aPath1,entry1,pos1);
1.41 + NextInPath(aPath2,entry2,pos2);
1.42 + if (entry1.MatchF(entry2)==KErrNotFound)
1.43 + return(EFalse);
1.44 + } while (entry1.Length() && entry2.Length());
1.45 +
1.46 + return(ETrue);
1.47 + }
1.48 +
1.49 +TBool CompareResource(const TDesC & aThePath)
1.50 +//
1.51 +//compare function for the Resource path true for match
1.52 +//
1.53 + {
1.54 + TInt pathLen = aThePath.Length();
1.55 + if(pathLen < KResourceLength)
1.56 + return EFalse;
1.57 + //if not word aligned then no less efficient than treating as TUint16
1.58 + const TUint32 * path32 = reinterpret_cast<const TUint32*>(aThePath.Ptr());
1.59 + if( (*path32 & 0xFFDFFFFF) != 0x0052005c) // '/R'
1.60 + return EFalse;
1.61 + path32++;
1.62 + if( (*path32 & 0xFFDFFFDF) != 0x00530045) // 'ES'
1.63 + return EFalse;
1.64 + path32++;
1.65 + if( (*path32 & 0xFFDFFFDF) != 0x0055004F) // 'OU'
1.66 + return EFalse;
1.67 + path32++;
1.68 + if( (*path32 & 0xFFDFFFDF) != 0x00430052) // 'RC'
1.69 + return EFalse;
1.70 + path32++;
1.71 + if(pathLen > KResourceLength)
1.72 + {
1.73 + if( (*path32 & 0xFFFFFFDF) != 0x005c0045) // 'E/'
1.74 + return EFalse;
1.75 + }
1.76 + else
1.77 + {
1.78 + if( (*path32 & 0x0000FFDF) != 0x00000045) // 'E'
1.79 + return EFalse;
1.80 + }
1.81 +
1.82 + return ETrue;
1.83 + }
1.84 +
1.85 +TBool CompareSystem(const TDesC & aThePath)
1.86 +//
1.87 +//compare function for the system path true for match
1.88 +//
1.89 + {
1.90 + TInt pathLen = aThePath.Length();
1.91 + if(pathLen < KSystemLength)
1.92 + return EFalse;
1.93 + //if not word aligned then no less efficient than treating as TUint16
1.94 + const TUint32 * path32 = reinterpret_cast<const TUint32*>(aThePath.Ptr());
1.95 + if( (*path32 & 0xFFDFFFFF) != 0x0053005c) // '/S'
1.96 + return EFalse;
1.97 + path32++;
1.98 + if( (*path32 & 0xFFDFFFDF) != 0x00530059) // 'YS
1.99 + return EFalse;
1.100 + if(pathLen == KSystemLength)
1.101 + return ETrue;
1.102 + path32++;
1.103 + if( (*path32 & 0x0000FFFF) != 0x0000005c) // '/'
1.104 + return EFalse;
1.105 +
1.106 + return ETrue;
1.107 + }
1.108 +
1.109 +TBool ComparePrivate(const TDesC & aThePath)
1.110 +//
1.111 +//compare function to compare if private path being accessed true for match
1.112 +//
1.113 + {
1.114 + TInt pathLen = aThePath.Length();
1.115 + if(pathLen < KPrivateLength)
1.116 + return EFalse;
1.117 + const TUint32 * path32 = reinterpret_cast<const TUint32*>(aThePath.Ptr());
1.118 +
1.119 + if((*path32 & 0xFFDFFFFF) != 0x0050005c) // '/P'
1.120 + return EFalse;
1.121 + path32++;
1.122 + if( (*path32 & 0xFFDFFFDF) != 0x00490052) // 'RI
1.123 + return EFalse;
1.124 + path32++;
1.125 + if( (*path32 & 0xFFDFFFDF) != 0x00410056) // 'VA'
1.126 + return EFalse;
1.127 + path32++;
1.128 + if( (*path32 & 0xFFDFFFDF) != 0x00450054) // 'TE'
1.129 + return EFalse;
1.130 + if(pathLen == KPrivateLength)
1.131 + return ETrue;
1.132 + path32++;
1.133 + if( (*path32 & 0x0000FFFF) != 0x0000005c) // '/'
1.134 + return EFalse;
1.135 +
1.136 + return ETrue;
1.137 + }
1.138 +
1.139 +TBool SIDCheck(CFsRequest* aRequest, const TDesC& aThePath)
1.140 +//
1.141 +// Compare the Private/XXXXXXXX/ portion of a path be accessed to make sure it matches the process SID
1.142 +//
1.143 + {
1.144 + if(aThePath.Length() >= KPrivateLengthCheck)
1.145 + {
1.146 + TSecureId appUID = aRequest->Message().SecureId();
1.147 + TBuf<KSIDLength+1> dirName;
1.148 + dirName.AppendNumFixedWidth(appUID.iId, EHex, 8);
1.149 +
1.150 + TInt match = dirName.CompareF(aThePath.Mid(KSIDPathOffset,KPrivateLength));
1.151 + if(match==KErrNone)
1.152 + return ETrue;
1.153 + else
1.154 + return EFalse;
1.155 + }
1.156 +
1.157 + return EFalse;
1.158 + }
1.159 +
1.160 +#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.161 +TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, const TSecurityPolicy* aROCap, const char* aDiag)
1.162 +#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.163 +TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, const TSecurityPolicy* aROCap, OnlyCreateWithNull /*aDiag*/)
1.164 +#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.165 +//
1.166 +// Compare the parsed path with protected path names path must be parsed b4 using
1.167 +//
1.168 + {
1.169 +
1.170 + if(aRequest->Message().Handle() == KLocalMessageHandle)
1.171 + return KErrNone;
1.172 +
1.173 +#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.174 +#ifdef _DEBUG
1.175 + TBuf8<512> diagmsg;
1.176 + TInt len = aThePath.Length();
1.177 + diagmsg.Append((TUint8*)aThePath.Ptr(),len*2);
1.178 + diagmsg.Collapse();
1.179 + diagmsg.SetLength(len);
1.180 + diagmsg.Append(_L(" Used to call: "));
1.181 + len = User::StringLength((const TUint8*)aDiag);
1.182 + diagmsg.Append((TUint8*)aDiag, len);
1.183 + const char* const diagout = (char*)diagmsg.PtrZ();
1.184 +#else //!_DEBUG
1.185 + const char* const diagout = aDiag;
1.186 +#endif //_DEBUG
1.187 +#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.188 +
1.189 + if(ComparePrivate(aThePath))
1.190 + {
1.191 + if(SIDCheck(aRequest, aThePath))
1.192 + return KErrNone;
1.193 + else
1.194 + {
1.195 + if(aPriCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
1.196 + return KErrNone;
1.197 + else
1.198 + return KErrPermissionDenied;
1.199 + }
1.200 + }
1.201 + else if(CompareSystem(aThePath))
1.202 + {
1.203 + if(aSysCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
1.204 + return KErrNone;
1.205 + else
1.206 + return KErrPermissionDenied;
1.207 + }
1.208 + else if(CompareResource(aThePath))
1.209 + {
1.210 + if(aROCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
1.211 + return KErrNone;
1.212 + else
1.213 + return KErrPermissionDenied;
1.214 + }
1.215 + else
1.216 + return KErrNone;
1.217 + }
1.218 +
1.219 +#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.220 +TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, const char* aDiag)
1.221 +#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.222 +TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, OnlyCreateWithNull /*aDiag*/)
1.223 +#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.224 +//
1.225 +// Compare the parsed path with protected path names path must be parsed b4 using
1.226 +//
1.227 + {
1.228 +
1.229 + if(aRequest->Message().Handle() == KLocalMessageHandle)
1.230 + return KErrNone;
1.231 +
1.232 +#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.233 +#ifdef _DEBUG
1.234 + TBuf8<512> diagmsg;
1.235 + TInt len = aThePath.Length();
1.236 + diagmsg.Append((TUint8*)aThePath.Ptr(),len*2);
1.237 + diagmsg.Collapse();
1.238 + diagmsg.SetLength(len);
1.239 + diagmsg.Append(_L(" Used to call: "));
1.240 + len = User::StringLength((const TUint8*)aDiag);
1.241 + diagmsg.Append((TUint8*)aDiag, len);
1.242 + const char* const diagout = (char*)diagmsg.PtrZ();
1.243 +#else //!_DEBUG
1.244 + const char* const diagout = aDiag;
1.245 +#endif //_DEBUG
1.246 +#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.247 +
1.248 + if(ComparePrivate(aThePath))
1.249 + {
1.250 + if(SIDCheck(aRequest, aThePath))
1.251 + return KErrNone;
1.252 + else
1.253 + {
1.254 + if(aPriCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
1.255 + return KErrNone;
1.256 + else
1.257 + return KErrPermissionDenied;
1.258 + }
1.259 + }
1.260 + else if(CompareSystem(aThePath))
1.261 + {
1.262 + if(aSysCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
1.263 + return KErrNone;
1.264 + else
1.265 + return KErrPermissionDenied;
1.266 + }
1.267 + else
1.268 + return KErrNone;
1.269 + }
1.270 +
1.271 +#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.272 +TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aCap, const char* aDiag, TBool aExactMatchAllowed)
1.273 +#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.274 +TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aCap, OnlyCreateWithNull /*aDiag*/, TBool aExactMatchAllowed)
1.275 +#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.276 +//
1.277 +// Compare the parsed path with protected path names path must be parsed b4 using
1.278 +//
1.279 + {
1.280 +
1.281 + if(aRequest->Message().Handle() == KLocalMessageHandle)
1.282 + return KErrNone;
1.283 +
1.284 +#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.285 +#ifdef _DEBUG
1.286 + TBuf8<512> diagmsg;
1.287 + TInt len = aThePath.Length();
1.288 + diagmsg.Append((TUint8*)aThePath.Ptr(),len*2);
1.289 + diagmsg.Collapse();
1.290 + diagmsg.SetLength(len);
1.291 + diagmsg.Append(_L(" Used to call: "));
1.292 + len = User::StringLength((const TUint8*)aDiag);
1.293 + diagmsg.Append((TUint8*)aDiag, len);
1.294 + const char* const diagout = (char*)diagmsg.PtrZ();
1.295 +#else //!_DEBUG
1.296 + const char* const diagout = aDiag;
1.297 +#endif //_DEBUG
1.298 +#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
1.299 +
1.300 + if(ComparePrivate(aThePath))
1.301 + {
1.302 + if(SIDCheck(aRequest, aThePath))
1.303 + return KErrNone;
1.304 + else
1.305 + {
1.306 + if(aCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
1.307 + return KErrNone;
1.308 + else if (aExactMatchAllowed && aThePath.Length() <= KPrivateLength + 1)
1.309 + return KErrNone;
1.310 + else
1.311 + return KErrPermissionDenied;
1.312 + }
1.313 + }
1.314 + else if(CompareSystem(aThePath))
1.315 + {
1.316 + if(aCap->CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING(diagout)))
1.317 + return KErrNone;
1.318 + else if (aExactMatchAllowed && aThePath.Length() <= KSystemLength + 1)
1.319 + return KErrNone;
1.320 + else
1.321 + return KErrPermissionDenied;
1.322 + }
1.323 + else
1.324 + return KErrNone;
1.325 +
1.326 + }
1.327 +
1.328 +
1.329 +
1.330 +
1.331 +void Fault(TFsFault aFault)
1.332 +//
1.333 +// Fault the file server.
1.334 +//
1.335 + {
1.336 +
1.337 + __PRINT1(_L("FAULT: TFsFault %d"),aFault);
1.338 + User::Panic(_L("Fserv fault"),aFault);
1.339 + }
1.340 +
1.341 +/**
1.342 + Get Ptr() from the client and parse it. Allow wild cards.
1.343 + Then get the drive and if the drive is substed get the real name.
1.344 +
1.345 + @param aP message parameter number
1.346 + @param aRequest pointer to the reques object
1.347 + @param aParse parser
1.348 + @param aUseSessionPath flag specifying whether the session path is to be
1.349 + used for parsing or not. Default value is ETrue meaning
1.350 + that the session path is used while parsing.
1.351 +
1.352 + @return system-wide error code.
1.353 +*/
1.354 +TInt ParseSubst(const TInt aP, CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath)
1.355 + {
1.356 + __ASSERT_DEBUG(aRequest->Session(),Fault(EParseSubstSession));
1.357 +
1.358 + //-- check the length of the name, passed by client.
1.359 + //-- it shall not be longer than KMaxFileName
1.360 + TInt nameLen=aRequest->GetDesLength(aP);
1.361 + if(nameLen < 0 || nameLen > KMaxFileName)
1.362 + return KErrBadName;
1.363 +
1.364 + TFileName n;
1.365 + TRAPD(r, aRequest->ReadL(aP,n));
1.366 +
1.367 + if(r==KErrNone)
1.368 + {
1.369 + if(aUseSessionPath)
1.370 + r=aParse.Set(n,NULL,&aRequest->Session()->Path());
1.371 + else
1.372 + r=aParse.Set(n,NULL,NULL);
1.373 + }
1.374 + if (r!=KErrNone)
1.375 + return(r);
1.376 + if(!aUseSessionPath && !aParse.DrivePresent())
1.377 + return(r);
1.378 + TInt drive;
1.379 + if ((r=RFs::CharToDrive(aParse.Drive()[0],drive))!=KErrNone)
1.380 + return(r);
1.381 + aRequest->SetDrive(&TheDrives[drive]);
1.382 + if (aRequest->Drive()->Att()&KDriveAttSubsted)
1.383 + {
1.384 + if ((aRequest->Drive()->Subst().Length()+aParse.FullName().Length())>(KMaxFileName+3))
1.385 + return(KErrBadName);
1.386 + aRequest->SetSubstedDrive(aRequest->Drive());
1.387 + // and now set aParse with the full path name
1.388 + n=aRequest->Drive()->Subst().Mid(2);
1.389 + n+=aParse.FullName().Mid(3);
1.390 + TFileName n2=aRequest->SubstedDrive()->Subst().Left(2);
1.391 + r=aParse.Set(n,NULL,&n2);
1.392 + if(r!=KErrNone)
1.393 + return(r);
1.394 + aRequest->SetDrive(&aRequest->Drive()->SubstedDrive());
1.395 + }
1.396 + return(KErrNone);
1.397 + }
1.398 +
1.399 +
1.400 +TInt ParseSubstPtr0(CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath)
1.401 +//
1.402 +// Get Ptr0() from the client and parse it. Allow wild cards.
1.403 +// Then get the drive and if the drive is substed get the real name.
1.404 +//
1.405 + {
1.406 +
1.407 + return(ParseSubst(KMsgPtr0,aRequest,aParse,aUseSessionPath));
1.408 + }
1.409 +
1.410 +TInt ParseNoWildSubstPtr0(CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath)
1.411 +//
1.412 +// Get Ptr0() from the client and parse it. Dis-allow wild cards.
1.413 +// Then get the drive and if the drive is substed get the real name.
1.414 +//
1.415 + {
1.416 + TInt r=ParseSubst(KMsgPtr0,aRequest,aParse,aUseSessionPath);
1.417 + if (r!=KErrNone)
1.418 + return(r); // Returns KErrBadName if "/" in the name or length > 256 chars
1.419 +
1.420 + if (aParse.IsWild()) // No *s or ?s allowed in the file name
1.421 + return(KErrBadName);
1.422 + return(KErrNone);
1.423 + }
1.424 +
1.425 +
1.426 +TInt ParseNoWildSubstPtr1(CFsRequest* aRequest,TParse& aParse)
1.427 +//
1.428 +// Get Ptr0() from the client and parse it. Dis-allow wild cards.
1.429 +// Then get the drive and if the drive is substed get the real name.
1.430 +//
1.431 + {
1.432 + TInt r=ParseSubst(KMsgPtr1, aRequest, aParse);
1.433 + if (r!=KErrNone)
1.434 + return(r); // Returns KErrBadName if "/" in the name or length > 256 chars
1.435 +
1.436 + if (aParse.IsWild()) // No *s or ?s allowed in the file name
1.437 + return(KErrBadName);
1.438 + return(KErrNone);
1.439 + }
1.440 +
1.441 +
1.442 +TInt ParseNoWildSubstCheckPathPtr0(CFsRequest* aRequest,TParse& aParse)
1.443 +//
1.444 +// Get Ptr0() from the client and parse it.
1.445 +// Then get the drive and if the drive is substed get the real name.
1.446 +// Dis-allow wild cards and the root directory
1.447 +//
1.448 + {
1.449 +
1.450 + TInt r=ParseSubst(KMsgPtr0,aRequest,aParse);
1.451 + if (r!=KErrNone)
1.452 + return(r);
1.453 + if (aParse.IsWild() || (aParse.IsRoot() && !aParse.NameOrExtPresent()))
1.454 + return(KErrBadName);
1.455 + return(KErrNone);
1.456 + }
1.457 +
1.458 +TInt ParseNoWildSubstCheckPathPtr1(CFsRequest* aRequest,TParse& aParse)
1.459 +//
1.460 +// Get Ptr1() from the client and parse it.
1.461 +// Then get the drive and if the drive is substed get the real name.
1.462 +// Dis-allow wild cards and the root directory
1.463 +//
1.464 + {
1.465 +
1.466 + TInt r=ParseSubst(KMsgPtr1,aRequest,aParse);
1.467 + if (r!=KErrNone)
1.468 + return(r);
1.469 + if (aParse.IsWild() || (aParse.IsRoot() && !aParse.NameOrExtPresent()))
1.470 + return(KErrBadName);
1.471 +
1.472 + return(KErrNone);
1.473 + }
1.474 +
1.475 +TInt ParseNoWildSubstFileCheckPtr1(CFsRequest* aRequest,TParse& aParse)
1.476 +//
1.477 +// Get Ptr0() from the client and parse it.
1.478 +// Then get the drive and if the drive is substed get the real name.
1.479 +// Dis-allow wild cards and the root directory
1.480 +// Finally check that there is a name or extension.
1.481 + {
1.482 +
1.483 + TInt r=ParseSubst(KMsgPtr1,aRequest,aParse);
1.484 + if (r!=KErrNone)
1.485 + return(r);
1.486 + if (aParse.IsWild() || (aParse.IsRoot() && !aParse.NameOrExtPresent()))
1.487 + return(KErrBadName);
1.488 + if(!aParse.NameOrExtPresent())
1.489 + return (KErrBadName);
1.490 + return(KErrNone);
1.491 + }
1.492 +
1.493 +TInt ParseNoWildSubstCheckPtr0(CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath)
1.494 +//
1.495 +// Get Ptr0() from the client and parse it. Dis-allow wild cards.
1.496 +// Then get the drive and if the drive is substed get the real name.
1.497 +// Finally check that there is a name or extension.
1.498 +//
1.499 + {
1.500 +
1.501 + TInt r=ParseNoWildSubstPtr0(aRequest,aParse, aUseSessionPath);
1.502 + if (r!=KErrNone)
1.503 + return(r);
1.504 + if (!aParse.NameOrExtPresent())
1.505 + return(KErrBadName);
1.506 + return(KErrNone);
1.507 + }
1.508 +
1.509 +TInt ParseNoWildSubstCheckPtr1(CFsRequest* aRequest,TParse& aParse)
1.510 +//
1.511 +// Get Ptr1() from the client and parse it. Dis-allow wild cards.
1.512 +// Then get the drive and if the drive is substed get the real name.
1.513 +// Finally check that there is a name or extension.
1.514 +//
1.515 + {
1.516 +
1.517 + TInt r=ParseNoWildSubstPtr1(aRequest,aParse);
1.518 + if (r!=KErrNone)
1.519 + return(r);
1.520 + if (!aParse.NameOrExtPresent())
1.521 + return(KErrBadName);
1.522 + return(KErrNone);
1.523 + }
1.524 +
1.525 +/**
1.526 + Get Ptr0() from the client and parse it.
1.527 +
1.528 + @param aRequest pointer to the reques object
1.529 + @param aParse parser
1.530 +
1.531 + @return system-wide error code.
1.532 +*/
1.533 +TInt ParsePathPtr0(CFsRequest* aRequest,TParse& aParse)
1.534 + {
1.535 + //-- check the length of the name, passed by client.
1.536 + //-- it shall not be longer than KMaxFileName
1.537 + TInt nameLen=aRequest->GetDesLength(KMsgPtr0);
1.538 + if(nameLen < 0 || nameLen > KMaxFileName)
1.539 + return KErrBadName;
1.540 +
1.541 + TFileName n;
1.542 + TRAPD(r,aRequest->ReadL(KMsgPtr0,n));
1.543 + if (r==KErrNone)
1.544 + r=aParse.SetNoWild(n,NULL,&aRequest->Session()->Path());
1.545 + if (r!=KErrNone)
1.546 + return(r);
1.547 + if (aParse.NameOrExtPresent())
1.548 + return(KErrBadName);
1.549 + TInt drive;
1.550 + if ((r=RFs::CharToDrive(aParse.Drive()[0],drive))!=KErrNone)
1.551 + return(r);
1.552 + aRequest->SetDrive(&TheDrives[drive]);
1.553 + return(KErrNone);
1.554 + }
1.555 +
1.556 +
1.557 +TInt ParseNotificationPath(CFsRequest* aRequest, TParse& aParse, TDes& aNotifyPath)
1.558 +//
1.559 +// Called by Notify Change extended function when client has submitted a path
1.560 +// which contains a wildcarded initial character to represent the drive
1.561 +// This is required when notification over a number of drives is required
1.562 +//
1.563 + {
1.564 + if ((aNotifyPath[0]==KMatchAny)||(aNotifyPath[0]==KMatchOne))
1.565 + {
1.566 + // Use the default session drive for now
1.567 + TFileName sessionDefault=aRequest->Session()->Path();
1.568 + aNotifyPath[0]=sessionDefault[0];
1.569 + }
1.570 +
1.571 + TInt r=aParse.Set(aNotifyPath,NULL,&aRequest->Session()->Path());
1.572 + if (r!=KErrNone)
1.573 + return(r);
1.574 + TInt drive;
1.575 + if ((r=RFs::CharToDrive(aParse.Drive()[0],drive))!=KErrNone)
1.576 + return(r);
1.577 + aRequest->SetDrive(&TheDrives[drive]);
1.578 + if (aRequest->Drive()->Att()&KDriveAttSubsted)
1.579 + {
1.580 + if ((aRequest->Drive()->Subst().Length()+aParse.FullName().Length())>(KMaxFileName+3))
1.581 + return(KErrBadName);
1.582 + aRequest->SetSubstedDrive(aRequest->Drive());
1.583 + // and now set aParse with the full path name
1.584 + TFileName n=aRequest->Drive()->Subst().Mid(2);
1.585 + n+=aParse.FullName().Mid(3);
1.586 + TFileName n2=aRequest->SubstedDrive()->Subst().Left(2);
1.587 + r=aParse.Set(n,NULL,&n2);
1.588 + if(r!=KErrNone)
1.589 + return(r);
1.590 + aRequest->SetDrive(&aRequest->Drive()->SubstedDrive());
1.591 + }
1.592 + if (aParse.IsWild())
1.593 + return(KErrBadName);
1.594 + return(KErrNone);
1.595 + }
1.596 +
1.597 +
1.598 +CFsObject* SessionObjectFromHandle(TInt aHandle,TInt aUniqueID, CSessionFs* aSession)
1.599 +//
1.600 +// Lookup an object from its handle.
1.601 +//
1.602 + {
1.603 + if(aUniqueID==0)
1.604 + return(aSession->Handles().At(aHandle,ETrue));
1.605 + else
1.606 + return(aSession->Handles().At(aHandle,aUniqueID,ETrue));
1.607 + }
1.608 +
1.609 +
1.610 +CFileShare* GetShareFromHandle(CSessionFs* aSession, TInt aHandle)
1.611 +//
1.612 +// Get the share control block from its handle.
1.613 +//
1.614 + {
1.615 + return((CFileShare*)(SessionObjectFromHandle(aHandle,FileShares->UniqueID(),aSession)));
1.616 + }
1.617 +
1.618 +
1.619 +//
1.620 +// Returns ETrue if aDes only contains spaces or is zero length
1.621 +//
1.622 +static TBool IsSpace(const TDesC& aDes)
1.623 + {
1.624 +
1.625 + TInt len=aDes.Length();
1.626 + if (len==0)
1.627 + return(EFalse);
1.628 + for (TInt i=0;i<len;i++)
1.629 + {
1.630 + TChar txt=aDes[i];
1.631 + if (!txt.IsSpace())
1.632 + return(EFalse);
1.633 + }
1.634 + return(ETrue);
1.635 + }
1.636 +
1.637 +TUint32 CalcNameHash(const TDesC& aName)
1.638 + {
1.639 + const TUint32 KNameHashCRCInitialiser=0x12345678;
1.640 + TUint32 hash=KNameHashCRCInitialiser;
1.641 + Mem::Crc32(hash, aName.Ptr(), aName.Size());
1.642 + return hash;
1.643 + }
1.644 +
1.645 +
1.646 +TBool TNameChecker::IsIllegal(TText& aChar) const
1.647 +//
1.648 +// Checks aChar != any of < > : " / |
1.649 +// \ is also illegal in a name but will be considered a path delimiter
1.650 +//
1.651 + {
1.652 + switch (aChar)
1.653 + {
1.654 + case '<':
1.655 + case '>':
1.656 + case ':':
1.657 + case '"':
1.658 + case '/':
1.659 + case '|':
1.660 + case '\000':
1.661 + return(ETrue);
1.662 + default:
1.663 + break;
1.664 + }
1.665 + return(EFalse);
1.666 + }
1.667 +
1.668 +
1.669 +
1.670 +TBool TNameChecker::IsIllegalChar(TText& aChar)
1.671 +//
1.672 +// Checks aName for illegal components and returns the offending character if any
1.673 +// No other parsing is performed
1.674 +//
1.675 + {
1.676 + TInt len=iName.Length();
1.677 + while (len--)
1.678 + {
1.679 + if (IsIllegal(iName[len]))// '<', '>', ':', '"', '/', '|' or '\000'?
1.680 + {
1.681 + aChar=iName[len];
1.682 + return(ETrue);
1.683 + }
1.684 + }
1.685 + return(EFalse);
1.686 + }
1.687 +
1.688 +
1.689 +TBool TNameChecker::IsIllegalName()
1.690 +//
1.691 +// Checks name is not _L(".") or _L("..") and that there are no illegal characters
1.692 +//
1.693 + {
1.694 +
1.695 + TInt pos=iName.LocateReverse(KPathDelimiter)+1;
1.696 + TPtrC fileName(iName.Ptr()+pos,iName.Length()-pos);
1.697 + SetName(fileName);
1.698 +
1.699 + if (iName==_L(".") || iName==_L("..") || IsSpace(iName))
1.700 + return ETrue;
1.701 + TInt len=iName.Length();
1.702 +
1.703 + while (len--)
1.704 + {
1.705 + if (IsIllegal(iName[len])) // '<', '>', ':', '"', '/', '|' or '\000'?
1.706 + return(ETrue);
1.707 + }
1.708 + return(EFalse);
1.709 + }
1.710 +
1.711 +
1.712 +TBool TNameChecker::IsIllegalName(TText& aChar)
1.713 +//
1.714 +// Check name and path are legal - if not, return the offending component
1.715 +//
1.716 + {
1.717 + TInt r=iParse.Set(iName,NULL,NULL);
1.718 + if (r!=KErrNone)
1.719 + return(ETrue); // Checks for names > 256 chars etc
1.720 +
1.721 + SetName(iParse.FullName());
1.722 + if (IsIllegalPath(aChar))
1.723 + return(ETrue); // Checks for illegal characters in path
1.724 +
1.725 + TInt nameStart=iParse.FullName().LocateReverse(KPathDelimiter)+1;
1.726 + r=(iParse.FullName().Mid(nameStart)).LocateReverse(KPathDelimiter)+1;
1.727 + TPtrC fileName(iName.Ptr()+r,iName.Length()-r);
1.728 + SetName(fileName);
1.729 +
1.730 + if (iName==_L(".") || iName==_L("..") || IsSpace(iName))
1.731 + {
1.732 + aChar=iName[0];
1.733 + return ETrue;
1.734 + }
1.735 +
1.736 + return (IsIllegalChar(aChar));
1.737 + }
1.738 +
1.739 +const TInt KSpace = ' ';
1.740 +TBool TNameChecker::IsIllegalPath()
1.741 +//
1.742 +// Checks the path does not contain wildcards or directories _L(".") or _L("..") or just spaces
1.743 +//
1.744 + {
1.745 +
1.746 + if (iName.Locate(KMatchOne)!=KErrNotFound || iName.Locate(KMatchAny)!=KErrNotFound)
1.747 + return(ETrue);
1.748 +
1.749 + TLex pathLex=iName;
1.750 + FOREVER
1.751 + {
1.752 + pathLex.Inc();
1.753 + if (pathLex.Remainder().Length()==0)
1.754 + break;
1.755 + TInt nextPath=pathLex.Remainder().Locate(KPathDelimiter);
1.756 + if (nextPath==0) // Reject double backslashes
1.757 + return(ETrue);
1.758 + if (nextPath==KErrNotFound)
1.759 + nextPath=pathLex.Remainder().Length();
1.760 + pathLex.Mark();
1.761 + pathLex.Inc(nextPath);
1.762 + SetName(pathLex.MarkedToken());
1.763 + if (IsIllegalName())
1.764 + return(ETrue);
1.765 + // check for tailing dots
1.766 + for(TInt i = pathLex.MarkedToken().Length() - 1; i >= 0; --i)
1.767 + {
1.768 + if (pathLex.MarkedToken()[i] == KExtDelimiter)
1.769 + {
1.770 + return ETrue;
1.771 + }
1.772 + else if (pathLex.MarkedToken()[i] == KSpace)
1.773 + {
1.774 + continue;
1.775 + }
1.776 + else
1.777 + {
1.778 + break;
1.779 + }
1.780 + }
1.781 + }
1.782 + return(EFalse);
1.783 + }
1.784 +
1.785 +
1.786 +TBool TNameChecker::IsIllegalPath(TText& aChar)
1.787 +//
1.788 +// Checks the path does not contain wildcards or directories _L(".") or _L("..") or just spaces
1.789 +// Returns the first offending character found (if any)
1.790 +//
1.791 + {
1.792 + if (iName.Locate(KMatchOne)!=KErrNotFound)
1.793 + {
1.794 + aChar=KMatchOne;
1.795 + return (ETrue);
1.796 + }
1.797 + if (iName.Locate(KMatchAny)!=KErrNotFound)
1.798 + {
1.799 + aChar=KMatchAny;
1.800 + return (ETrue);
1.801 + }
1.802 +
1.803 + TLex pathLex=iName;
1.804 + TFileName name;
1.805 + FOREVER
1.806 + {
1.807 + pathLex.Inc();
1.808 + if (pathLex.Remainder().Length()==0)
1.809 + break;
1.810 + TInt nextPath=pathLex.Remainder().Locate(KPathDelimiter);
1.811 + if (nextPath==0) // Reject double backslashes
1.812 + {
1.813 + aChar=KPathDelimiter;
1.814 + return ETrue;
1.815 + }
1.816 + if (nextPath==KErrNotFound)
1.817 + nextPath=pathLex.Remainder().Length();
1.818 + pathLex.Mark();
1.819 + pathLex.Inc(nextPath);
1.820 + name=pathLex.MarkedToken();
1.821 + // check for tailing dots
1.822 + for(TInt i = pathLex.MarkedToken().Length() - 1; i >= 0; --i)
1.823 + {
1.824 + if (pathLex.MarkedToken()[i] == KExtDelimiter)
1.825 + {
1.826 + aChar = KExtDelimiter;
1.827 + return ETrue;
1.828 + }
1.829 + else if (pathLex.MarkedToken()[i] == KSpace)
1.830 + {
1.831 + continue;
1.832 + }
1.833 + else
1.834 + {
1.835 + break;
1.836 + }
1.837 + }
1.838 + TInt pos=name.LocateReverse(KPathDelimiter)+1;
1.839 + TPtrC fileName(name.Ptr()+pos,name.Length()-pos);
1.840 + SetName(fileName);
1.841 + if (iName==_L(".") || iName==_L("..") || IsSpace(iName))
1.842 + {
1.843 + aChar=iName[0];
1.844 + return ETrue;
1.845 + }
1.846 +
1.847 + if (IsIllegalChar(aChar))
1.848 + return(ETrue);
1.849 + }
1.850 +
1.851 + return(EFalse);
1.852 + }
1.853 +
1.854 +
1.855 +TBool IsIllegalFullName(const TParse& aParse)
1.856 + {
1.857 + TPtrC ptr=aParse.Path();
1.858 + TNameChecker checker(ptr);
1.859 + if (checker.IsIllegalPath())
1.860 + return(ETrue); // Checks for illegal characters in path
1.861 +
1.862 + TInt nameStart=aParse.FullName().LocateReverse(KPathDelimiter)+1;
1.863 + checker.SetName(aParse.FullName().Mid(nameStart));
1.864 +
1.865 + if (checker.IsIllegalName())
1.866 + return(ETrue); // Checks illegal characters such as ></|". and ..
1.867 + return(EFalse);
1.868 + }
1.869 +
1.870 + TBool IsIllegalFullName(const TDesC& aName)
1.871 +//
1.872 +// Check name and path are legal
1.873 +//
1.874 + {
1.875 + TParse parser;
1.876 + TInt r=parser.Set(aName,NULL,NULL);
1.877 + if (r!=KErrNone)
1.878 + return(ETrue); // Checks for wild cards, names>256 chars etc
1.879 +
1.880 + return IsIllegalFullName(parser);
1.881 + }
1.882 +
1.883 +TBool PowerOk()
1.884 +//
1.885 +// Check the power is OK
1.886 +//
1.887 + {
1.888 +
1.889 + TBool powerGood=EFalse;
1.890 + TInt r=HAL::Get(HAL::EPowerGood, powerGood);
1.891 + if (r!=KErrNone)
1.892 + return EFalse;
1.893 + return powerGood;
1.894 + }
1.895 +
1.896 +void AddResource(CMountCB& aMount)
1.897 +//
1.898 +// Decrement resource counters
1.899 +//
1.900 + {
1.901 + __CHECK_DRIVETHREAD(aMount.Drive().DriveNumber());
1.902 + __ASSERT_DEBUG(aMount.LockStatus()<=0,Fault(ERawDiskBadAccessCount2));
1.903 + aMount.DecLock();
1.904 + }
1.905 +
1.906 +void RemoveResource(CMountCB& aMount)
1.907 +//
1.908 +// Increment resource counters
1.909 +//
1.910 + {
1.911 + __ASSERT_DEBUG(aMount.LockStatus()<0,Fault(ERawDiskBadAccessCount1));
1.912 + aMount.IncLock();
1.913 + }
1.914 +
1.915 +
1.916 +void AddDiskAccess(CMountCB& aMount)
1.917 +//
1.918 +// Increment resource counters
1.919 +//
1.920 + {
1.921 + aMount.IncLock();
1.922 + }
1.923 +
1.924 +void RemoveDiskAccess(CMountCB& aMount)
1.925 +//
1.926 +// Decrement resource counters
1.927 +//
1.928 + {
1.929 + aMount.DecLock();
1.930 + }
1.931 +
1.932 +EXPORT_C void AllocBufferL(HBufC*& aBuf,const TDesC& aName)
1.933 +//
1.934 +// Alloc or ReAlloc buffer
1.935 +//
1.936 + {
1.937 +
1.938 + if (aBuf==NULL)
1.939 + {
1.940 + aBuf=aName.AllocL();
1.941 + return;
1.942 + }
1.943 + if (aBuf->Length()<aName.Length())
1.944 + {
1.945 + TInt bufGranularity=(1<<KLog2BufGranularity);
1.946 + TInt size=((aName.Length()+bufGranularity-1)>>KLog2BufGranularity)<<KLog2BufGranularity;
1.947 + aBuf=aBuf->ReAllocL(size);
1.948 + }
1.949 + aBuf->Des()=aName;
1.950 + }
1.951 +
1.952 +void NextInPath(const TDesC& aPath,TPtrC& anEntry,TInt& aPos)
1.953 +//
1.954 +// Returns the next entry in the path
1.955 +//
1.956 + {
1.957 +
1.958 + anEntry.Set(NULL,0);
1.959 + if ((aPos+1)>=aPath.Length())
1.960 + return;
1.961 + TPtrC path(aPath.Mid(aPos+1)); // Skip delimiter
1.962 + TInt delimiterPos=path.Locate(KPathDelimiter);
1.963 + if (delimiterPos==KErrNotFound)
1.964 + delimiterPos=aPath.Length()-(aPos+1);
1.965 + if (delimiterPos<=0)
1.966 + return;
1.967 +
1.968 + if (path[delimiterPos-1]==KExtDelimiter) // return "F32." as "F32"
1.969 + anEntry.Set(aPath.Mid(aPos+1,delimiterPos-1));
1.970 + else
1.971 + anEntry.Set(aPath.Mid(aPos+1,delimiterPos));
1.972 + aPos+=delimiterPos+1;
1.973 + }
1.974 +
1.975 +TInt MatchUidType(const TUidType &aMatch, const TUidType &aType)
1.976 +//
1.977 +// Compare aType against aMatch with KNullUid as a wildcard
1.978 +//
1.979 + {
1.980 +
1.981 + TUid mu=aMatch[2];
1.982 + TUid tu=aType[2];
1.983 + if (mu!=KNullUid && tu!=KNullUid && mu!=tu)
1.984 + return KErrNotSupported;
1.985 + mu=aMatch[1];
1.986 + tu=aType[1];
1.987 + if (mu!=KNullUid && tu!=KNullUid && mu!=tu)
1.988 + return KErrNotSupported;
1.989 + mu=aMatch[0];
1.990 + tu=aType[0];
1.991 + if (mu!=KNullUid && tu!=KNullUid && mu!=tu)
1.992 + return KErrNotSupported;
1.993 + return KErrNone;
1.994 + }
1.995 +
1.996 +/**
1.997 + * Compare sections of filenames according to locale-independent rules as well
1.998 + * as locale-dependent rules. This is an attempt to get an ordering where
1.999 + * equivalent names sort together but the overall ordering is culturally
1.1000 + * acceptable. Sadly, the ordering it gives is not consistent, and it is not
1.1001 + * clear how to make it so. Hence this function is deprecated. The correct way
1.1002 + * to do this is to code around it: If you need a sorted array for display that
1.1003 + * you also need to search for equivalent filenames, either use a linear search
1.1004 + * or keep two arrays, one sorted with CompareF, the other with CompareC.
1.1005 + * @deprecated 6.1
1.1006 + */
1.1007 +EXPORT_C TInt CompareFilenames(const TDesC& aFileName1,const TDesC& aFileName2)
1.1008 +//
1.1009 +// Compare filenames. Case is ignored and names are normalised
1.1010 +// (base+accent is equal to composed character) but spaces
1.1011 +// and punctuation are significant for determining equality.
1.1012 +// Whether two filenames are identical is the same in all
1.1013 +// locales, but the ordering of non-identical filenames is locale-specific.
1.1014 +//
1.1015 +//
1.1016 + {
1.1017 + // Create a non-locale-specific collation method that doesn't ignore spaces and punctuation but folds case.
1.1018 + TCollationMethod method;
1.1019 + method.iFlags = TCollationMethod::EIgnoreNone | TCollationMethod::EFoldCase;
1.1020 + method.iMainTable=NULL;
1.1021 + method.iOverrideTable=NULL;
1.1022 +
1.1023 + // Get the non-locale-specific order and return it if the names are equal.
1.1024 + TInt base_order = aFileName1.CompareC(aFileName2,3,&method);
1.1025 + if (base_order == 0)
1.1026 + return base_order;
1.1027 +
1.1028 + // Get the locale-specific order and use it unless it is equality, in which case the non-locale-specific order must be used.
1.1029 + TInt locale_order = aFileName1.CompareC(aFileName2);
1.1030 + return locale_order ? locale_order : base_order;
1.1031 + }
1.1032 +
1.1033 +void Get8BitDllName(TDes8& aDllName, const TDesC& aFileName)
1.1034 +//
1.1035 +// Convert a 16 bit name to an 8 bit name
1.1036 +// No data loss because UNICODE Dlls are currently restricted to 8 bit names
1.1037 +// No effect in 8 bit builds - just sets aDllName to aFileName
1.1038 +//
1.1039 + {
1.1040 + aDllName.SetLength(aFileName.Length());
1.1041 + aDllName.Copy(aFileName);
1.1042 + }
1.1043 +
1.1044 +void Get16BitDllName(TDes& aFileName, const TDesC8& aDllName)
1.1045 +//
1.1046 +// Convert an 8 bit name to a 16 bit name - zero padded automatically
1.1047 +// No effect in 8 bit builds - just sets aFileName to aDllName
1.1048 +//
1.1049 + {
1.1050 + aFileName.SetLength(aDllName.Length());
1.1051 + aFileName.Copy(aDllName);
1.1052 + }
1.1053 +
1.1054 +
1.1055 +/**
1.1056 + Checks that there is sufficient disk space available to complete a task taking into account reserved space
1.1057 +
1.1058 + @param aThreshold amount of required free space, in bytes
1.1059 + @param aRequest
1.1060 +
1.1061 + @return KErrNone on success and if there are _strictly_more_ than aThreshold bytes available on the volume (taking into account reserved space)
1.1062 + KErrDiskFull on success and if there isn't enough space
1.1063 + system-wide error code otherwise
1.1064 +*/
1.1065 +TInt CheckDiskSpace(TInt64 aThreshold, CFsRequest* aRequest)
1.1066 + {
1.1067 + const TInt KReservedSpace = aRequest->Drive()->ReservedSpace();
1.1068 + const TInt KDriveNumber = aRequest->Drive()->DriveNumber();
1.1069 +
1.1070 + if(KReservedSpace == 0 || KDriveNumber == EDriveZ)
1.1071 + return KErrNone;
1.1072 +
1.1073 + //-- if the drive has a reserved space, take it into account
1.1074 + CSessionFs* session=aRequest->Session();
1.1075 +
1.1076 + if(!session || !session->ReservedAccess(KDriveNumber))
1.1077 + aThreshold += KReservedSpace;
1.1078 +
1.1079 + //-- ask the corresponding file system if there is aThreshold bytes available.
1.1080 + //-- for some reason it's required to be strictly > than aThreshold
1.1081 + return aRequest->Drive()->RequestFreeSpaceOnMount(aThreshold+1);
1.1082 + }
1.1083 +
1.1084 +
1.1085 +#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1.1086 +EXPORT_C TUint32 DebugRegister() {return(DebugReg);}
1.1087 +#else
1.1088 +EXPORT_C TUint32 DebugRegister() {return(0);}
1.1089 +#endif
1.1090 +
1.1091 +CLogon* CLogon::NewL()
1.1092 +//
1.1093 +// Create the CLogon active object.
1.1094 +//
1.1095 + {
1.1096 +
1.1097 + CLogon* pL=new(ELeave) CLogon(EPriority);
1.1098 + CActiveScheduler::Add(pL);
1.1099 + return(pL);
1.1100 + }
1.1101 +
1.1102 +#pragma warning( disable : 4705 ) // statement has no effect
1.1103 +CLogon::CLogon(TInt aPriority)
1.1104 +//
1.1105 +// Constructor
1.1106 +//
1.1107 + : CActive(aPriority)
1.1108 + {
1.1109 + }
1.1110 +#pragma warning( default : 4705 )
1.1111 +
1.1112 +TInt CLogon::Logon(RThread aThread)
1.1113 +//
1.1114 +// Issue a request to logon to the thread.
1.1115 +//
1.1116 + {
1.1117 +
1.1118 + iThread=aThread;
1.1119 + iThread.Logon(iStatus);
1.1120 + SetActive();
1.1121 + if (iStatus==KErrNoMemory)
1.1122 + iThread.Kill(KErrNoMemory);
1.1123 + else
1.1124 + iThread.Resume();
1.1125 + iThread.Close();
1.1126 + CActiveScheduler::Start();
1.1127 + return(iStatus.Int());
1.1128 + }
1.1129 +
1.1130 +void CLogon::DoCancel()
1.1131 +//
1.1132 +// Cancel a pending event.
1.1133 +//
1.1134 + {
1.1135 +
1.1136 + iThread.LogonCancel(iStatus);
1.1137 + }
1.1138 +
1.1139 +void CLogon::RunL()
1.1140 +//
1.1141 +// Thread has terminated.
1.1142 +//
1.1143 + {
1.1144 +
1.1145 + CActiveScheduler::Stop();
1.1146 + }
1.1147 +