appfw/apparchitecture/aplist/aplappregfinder.cpp
changeset 0 2e3d3ce01487
child 12 7645e9ce10dc
child 35 13fd6fd25fe7
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 2004-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 "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 // aplappregfinder.cpp
       
    15 //
       
    16 
       
    17 #include "aplappregfinder.h"
       
    18 #include "APFDEF.H"
       
    19 #include "../apfile/APFSTD.H"
       
    20 #include "../apserv/apsserv.h"				// class CApaAppListServer
       
    21 #include "../apgrfx/apprivate.h"
       
    22 #include <apsidchecker.h>
       
    23 #include "aplapplistitem.h"					// class TApaAppEntry
       
    24 #include "aplappinforeader.h"				// class ApaUtils
       
    25 
       
    26 
       
    27 GLDEF_C void Panic(TApfPanic aPanic)
       
    28 	{
       
    29 	_LIT(KApFilePanic,"APFILE");
       
    30 	User::Panic(KApFilePanic,aPanic);
       
    31 	}
       
    32 
       
    33 
       
    34 //
       
    35 // CApaAppRegFinder
       
    36 //
       
    37 
       
    38 EXPORT_C CApaAppRegFinder* CApaAppRegFinder::NewL(const RFs& aFs)
       
    39 	{
       
    40 	CApaAppRegFinder* self=NewLC(aFs);
       
    41 	CleanupStack::Pop(self);
       
    42 	return self;
       
    43 	}
       
    44 	
       
    45 EXPORT_C CApaAppRegFinder* CApaAppRegFinder::NewLC(const RFs& aFs)
       
    46 	{
       
    47 	CApaAppRegFinder* self=new (ELeave) CApaAppRegFinder(aFs);
       
    48 	CleanupStack::PushL(self);
       
    49 	self->ConstructL();
       
    50 	return self;
       
    51 	}
       
    52 	
       
    53 CApaAppRegFinder::CApaAppRegFinder(const RFs& aFs)
       
    54 	: iFs(aFs),
       
    55 	iSidCheckerMap(CApaAppArcServer::Self()?CApaAppArcServer::Self()->RescanCallBack():TCallBack(NULL,NULL))
       
    56 	{
       
    57 	}
       
    58 
       
    59 CApaAppRegFinder::~CApaAppRegFinder()
       
    60 	{
       
    61 	iListOfDrives.Close();
       
    62 	iSidCheckerMap.Close();
       
    63 	delete iFileList; // should already be deleted and NULL at this point
       
    64 	}
       
    65 
       
    66 void CApaAppRegFinder::ConstructL()
       
    67 	{
       
    68 	}
       
    69 
       
    70 
       
    71 // Build a list of currently available drives
       
    72 void CApaAppRegFinder::RebuildDriveListL(TScanScope aScopeOfScan)
       
    73 	{
       
    74 	iListOfDrives.Reset();
       
    75 	TDriveList driveList;
       
    76 	User::LeaveIfError(iFs.DriveList(driveList));
       
    77 
       
    78 	// Scan through all the drives in the drive list from Y to A, querying the 
       
    79 	// file server about wheather the drives are pressent or not
       
    80 
       
    81 	TInt drive(EDriveY);
       
    82 	TDriveUnitInfo driveUnitInfo;
       
    83 	while(drive >= EDriveA)
       
    84 		{
       
    85 		// If the drive exists in the file system...
       
    86 		if (driveList[drive]!=KDriveAbsent)
       
    87 			{
       
    88 			TDriveInfo driveInfo;
       
    89 			const TInt err = iFs.Drive(driveInfo, drive);
       
    90 			if (!err)
       
    91 				{
       
    92 				if (aScopeOfScan == EScanRemovableDrives)
       
    93 					{// iListOfDrives should have list of all the removable drives irrespective of presence of the media
       
    94 					if ((driveInfo.iType != EMediaRemote) && (driveInfo.iDriveAtt & KDriveAttRemovable))
       
    95 						{
       
    96 						driveUnitInfo.iUnit=drive;
       
    97 						driveUnitInfo.iAttribs=driveInfo.iDriveAtt;
       
    98 						iListOfDrives.AppendL(driveUnitInfo);
       
    99 						}
       
   100 					}
       
   101 				else // scan all drives
       
   102 					{
       
   103 					if (driveInfo.iType!=EMediaNotPresent && driveInfo.iType!=EMediaRemote)
       
   104 						{
       
   105 						driveUnitInfo.iUnit=drive;
       
   106 						driveUnitInfo.iAttribs=driveInfo.iDriveAtt;
       
   107 						iListOfDrives.AppendL(driveUnitInfo);
       
   108 						}
       
   109 					}
       
   110 				}
       
   111 			}
       
   112 			
       
   113 		--drive;
       
   114 		}
       
   115 
       
   116 	// Add the Z-drive to the list if scanning all drives (not only removable)
       
   117 	if (aScopeOfScan == EScanAllDrives)
       
   118 		{
       
   119 		driveUnitInfo.iUnit=EDriveZ;
       
   120 		driveUnitInfo.iAttribs=KDriveAttRom;
       
   121 		iListOfDrives.AppendL(driveUnitInfo);
       
   122 		}
       
   123 	}
       
   124 
       
   125 EXPORT_C TArray<const TDriveUnitInfo> CApaAppRegFinder::DriveList() const
       
   126 	{
       
   127 	return iListOfDrives.Array();
       
   128 	}
       
   129 
       
   130 EXPORT_C void CApaAppRegFinder::FindAllAppsL(TScanScope aScopeOfScan)
       
   131 	{
       
   132 	delete iFileList;
       
   133 	iFileList = NULL;
       
   134 	RebuildDriveListL(aScopeOfScan);
       
   135 	iCurrentIndexInDriveList=-1;
       
   136 	iScanStage = EScanStageNonImportROM;
       
   137 	iLastChkedApp = KNullUid;	
       
   138 	}
       
   139 
       
   140 /** Scans the applications in following order:
       
   141 1. non-import y-a,z but only on ROM drives
       
   142 2. import on all non-ROM drives in the order y-a,z
       
   143 3. import on all ROM drives in the order y-a,z
       
   144 
       
   145 Upgrades of apparc server (via Software Install) are currently disallowed. 
       
   146 This means it is not possible to install registration files to \private\10003a3f\apps 
       
   147 (on any drive), so there is no need to scan \private\10003a3f\apps on non ROM based drives.
       
   148 */
       
   149 EXPORT_C TBool CApaAppRegFinder::NextL(TApaAppEntry& aAppRegistrationEntry, const CDesCArray& aForcedRegistrations)
       
   150 	{
       
   151 	__ASSERT_ALWAYS(iListOfDrives.Count(),Panic(EPanicFindAllAppsNotCalled));
       
   152 
       
   153 	FOREVER	// Continue until we have looked at all apps on all drives
       
   154 		{
       
   155 		TDriveUnitInfo currentDrive;
       
   156 		TPtrC appFolderOnDrive;
       
   157 		
       
   158 		if (!iFileList)	// If the file list has been exhausted...
       
   159 			{
       
   160 			iFileIndex = 0;
       
   161 			
       
   162 			// Look at the next drive until we find one with applications on it, or we run out of drives.
       
   163 			while(NextDriveAndFolderInNormalizedOrder(currentDrive, appFolderOnDrive))	
       
   164 				{
       
   165 				const TInt err = GetAppListOfDriveL(currentDrive.iUnit, appFolderOnDrive, iFileList);	// ...and create a new list for the next drive.
       
   166 				if(!err)	
       
   167 					break;	// Found a drive with applications on it
       
   168 				}
       
   169 				
       
   170 			if (!iFileList)		// If we've run out of drives
       
   171 				return EFalse; 	// ...then signal this by returning false.
       
   172 			}
       
   173 		else	// Still apps in the current list. Recall the current drive and path.
       
   174 			GetCurrentDriveAndFolder(currentDrive, appFolderOnDrive);
       
   175 
       
   176 		// Scan the list of all app files for application reg-files
       
   177 		while (iFileIndex < iFileList->Count())
       
   178 			{
       
   179 			const TEntry& entry=(*iFileList)[iFileIndex++];
       
   180 			if (!ApaUtils::TypeUidIsForRegistrationFile(entry.iType))
       
   181 				continue; // Only interested in app registration resource files
       
   182 				
       
   183 			// File is application reg-file
       
   184 			
       
   185 			// Build a parse-object for the full ref-file name
       
   186 			TParse regFileNameParser;
       
   187 			const TDriveName driveName = currentDrive.iUnit.Name();
       
   188 			regFileNameParser.Set(entry.iName, &appFolderOnDrive, &driveName);
       
   189 
       
   190 			// If the appliation is located on a removable drive...
       
   191 			if (currentDrive.iAttribs&KDriveAttRemovable)
       
   192 				{
       
   193 				// ...then verify that there is a valid Secure ID (SID) for the appliation
       
   194 				// to protect against untrusted applications.
       
   195 				if (entry[2] != iLastChkedApp) //Check for validity only if it has not yet been checked
       
   196 					{
       
   197 					const TUid appTypeUid = 
       
   198 					(entry[0].iUid == KUidPrefixedNonNativeRegistrationResourceFile ? entry[1] : KNullUid);
       
   199 				
       
   200 					// Get the CAppSidChecker for this type of executable
       
   201 					TBool validRegistration = ETrue;
       
   202 					TRAPD(err, validRegistration = iSidCheckerMap.FindSidCheckerL(appTypeUid).AppRegisteredAt(entry[2], currentDrive.iUnit));
       
   203 					iLastChkedApp = entry[2];
       
   204 					if(!err)
       
   205 						{
       
   206 						if(!validRegistration)	// If not trusted...
       
   207 							{
       
   208 							// Check if this registration file should be included despite 
       
   209 							// not being officially reported as a valid registration
       
   210 							const TPtrC fullName = regFileNameParser.FullName();
       
   211 							TInt ignorePos = KErrNotFound;
       
   212 							if (aForcedRegistrations.FindIsq(fullName, ignorePos, ECmpFolded) != 0)	// If not found
       
   213 								continue;	// App is not trusted. Move on to the next!
       
   214 							}
       
   215 						// App is trusted! Fall through.
       
   216 						}
       
   217 					else if(err != KErrNotFound)
       
   218 						User::LeaveIfError(err);
       
   219 					else
       
   220 						continue; // Can't tell. Move on to next.
       
   221 					}
       
   222 				else
       
   223 					{
       
   224 					continue;
       
   225 					}
       
   226 				}
       
   227 	
       
   228 			// App was found to be trustworthy	
       
   229 			aAppRegistrationEntry.iUidType = entry.iType;
       
   230 			aAppRegistrationEntry.iFullName = regFileNameParser.FullName();
       
   231 			return ETrue;	// Break out of the loop!
       
   232 			}
       
   233 			
       
   234 		// Current drive has been exhausted...
       
   235 		delete iFileList;
       
   236 		iFileList = NULL;
       
   237 		} // ...loop and check the next drive for apps.
       
   238 	}
       
   239 	
       
   240 void CApaAppRegFinder::GetCurrentDriveAndFolder(TDriveUnitInfo& aDrive, TPtrC& aAppFolderOnDrive) const
       
   241 	{
       
   242 	ASSERT(iCurrentIndexInDriveList != KErrNotFound && iCurrentIndexInDriveList < iListOfDrives.Count());
       
   243 	aDrive = iListOfDrives[iCurrentIndexInDriveList];
       
   244 	aAppFolderOnDrive.Set(iFolderOnCurrentDrive);
       
   245 	}
       
   246 	
       
   247 TBool CApaAppRegFinder::NextDriveAndFolderInNormalizedOrder(TDriveUnitInfo& aNextDrive, TPtrC& aAppFolderOnDrive) const
       
   248 	{
       
   249 _LIT(KAppRegRscSearchPath,"\\private\\10003a3f\\apps\\");
       
   250 _LIT(KAppRegRscImportSearchPath,"\\private\\10003a3f\\import\\apps\\");
       
   251 _LIT(KAppRegRscImportNonNativeSearchPath,"\\private\\10003a3f\\import\\apps\\NonNative\\Resource\\");
       
   252 
       
   253 	// Updates iCurrentIndexInDriveList
       
   254 	// 
       
   255 	TBool foundAnotherDrive = ETrue;
       
   256 	FOREVER
       
   257 		{
       
   258 		iCurrentIndexInDriveList++;	// move to next folder
       
   259 		if (iCurrentIndexInDriveList >= iListOfDrives.Count())	// If we reached the end if the drive list...
       
   260 			{
       
   261 			ASSERT(iScanStage < EScanStageComplete);
       
   262 			iCurrentIndexInDriveList = 0;		// ...start over from the beginning of the drive list
       
   263 			iScanStage++;						// ...and start looking for drives of the next type
       
   264 			}
       
   265 		
       
   266 		// Get next drive's info
       
   267 		const TDriveUnitInfo driveUnitInfo = iListOfDrives[iCurrentIndexInDriveList];
       
   268 		
       
   269 		// Check if this drive is of the correct type for this next stage
       
   270 		switch (iScanStage)
       
   271 			{
       
   272 			case EScanStageNonImportROM:
       
   273 			// Stage 1: Look in the non-import folder on ROM drives
       
   274 				if (driveUnitInfo.iAttribs==KDriveAttRom)
       
   275 					{
       
   276 					aAppFolderOnDrive.Set(KAppRegRscSearchPath);
       
   277 					goto done;	// Break out of the loop to return the drive found
       
   278 					}
       
   279 				break;	// Break and move on to the next drive
       
   280 			case EScanStageImportNonROM:	
       
   281 			// Stage 2: Look in the import folder for native apps on non-ROM drives
       
   282 				if (driveUnitInfo.iAttribs!=KDriveAttRom)
       
   283 					{
       
   284 					aAppFolderOnDrive.Set(KAppRegRscImportSearchPath);
       
   285 					goto done;	// Break out of the loop to return the drive found
       
   286 					}
       
   287 				break; // Break and move on to the next drive
       
   288 			case EScanStageImportNonNativeResourceNonROM:
       
   289 			// Stage 3: Look in the import folder for non-native apps on non-ROM drives
       
   290 				if (driveUnitInfo.iAttribs!=KDriveAttRom)
       
   291 					{
       
   292 					aAppFolderOnDrive.Set(KAppRegRscImportNonNativeSearchPath);
       
   293 					goto done;	// Break out of the loop to return the drive found
       
   294 					}
       
   295 				break; // Break and move on to the next drive
       
   296 			case EScanStageImportROM:
       
   297 			// Stage 4: Look in import folder for native apps on ROM drives
       
   298 				if (driveUnitInfo.iAttribs==KDriveAttRom)
       
   299 					{
       
   300 					aAppFolderOnDrive.Set(KAppRegRscImportSearchPath);
       
   301 					goto done;	// Break out of the loop to return the drive found
       
   302 					}
       
   303 				break; // Break and move on to the next drive
       
   304 			case EScanStageImportNonNativeResourceROM:
       
   305 			// Stage 5: Look in the import folder for non-native apps on ROM drives
       
   306 				if (driveUnitInfo.iAttribs==KDriveAttRom)
       
   307 					{
       
   308 					aAppFolderOnDrive.Set(KAppRegRscImportNonNativeSearchPath);
       
   309 					goto done;	// Break out of the loop to return the drive found
       
   310 					}
       
   311 				break; // Break and move on to the next drive
       
   312 			case EScanStageComplete:
       
   313 			// Stage 6: All done!
       
   314 				aAppFolderOnDrive.Set(KNullDesC);
       
   315 				foundAnotherDrive = EFalse;
       
   316 				goto done;
       
   317 			default:
       
   318 				ASSERT(0);
       
   319 				break;	
       
   320 			}
       
   321 		}
       
   322 
       
   323 done:		
       
   324 	aNextDrive = (foundAnotherDrive) ? iListOfDrives[iCurrentIndexInDriveList] : TDriveUnitInfo();
       
   325 	iFolderOnCurrentDrive.Set(aAppFolderOnDrive);	// Remember the folder path for GetCurrentDriveAndFolder()
       
   326 	return foundAnotherDrive;
       
   327 	}	
       
   328 	
       
   329 _LIT(KAppRegRscSearchAnyFile,"*");
       
   330 
       
   331 TInt CApaAppRegFinder::GetAppListOfDriveL(TDriveUnit aDriveUnit, const TDesC& aPath, CDir*& aFileList) const
       
   332 	{
       
   333 	const TDriveName driveName = aDriveUnit.Name();
       
   334 	TParse regFileNameParser;
       
   335 	TInt error = regFileNameParser.Set(KAppRegRscSearchAnyFile, &aPath, &driveName);
       
   336 	User::LeaveIfError(error);
       
   337 	
       
   338 	ASSERT(!aFileList);
       
   339 	error = iFs.GetDir(regFileNameParser.FullName(), KEntryAttAllowUid, ESortNone, aFileList);
       
   340 	LeaveIfIrregularErrorL(error);
       
   341 	return error;
       
   342 	}
       
   343 
       
   344 void CApaAppRegFinder::LeaveIfIrregularErrorL(TInt aError)	// e.g. KErrNoMemory
       
   345 // static
       
   346 	{
       
   347 	if (aError!=KErrNone && aError!=KErrNotFound && aError!=KErrPathNotFound && aError!=KErrNotReady
       
   348 		&& aError!=KErrDisMounted && aError!=KErrCorrupt && aError!=KErrNotSupported && 
       
   349 		aError!=KErrBadName && aError!=KErrLocked)
       
   350 		{
       
   351 		User::Leave(aError);
       
   352 		}
       
   353 	}