appfw/apparchitecture/aplist/aplappregfinder.cpp
changeset 0 2e3d3ce01487
child 12 7645e9ce10dc
child 35 13fd6fd25fe7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/appfw/apparchitecture/aplist/aplappregfinder.cpp	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,353 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// aplappregfinder.cpp
+//
+
+#include "aplappregfinder.h"
+#include "APFDEF.H"
+#include "../apfile/APFSTD.H"
+#include "../apserv/apsserv.h"				// class CApaAppListServer
+#include "../apgrfx/apprivate.h"
+#include <apsidchecker.h>
+#include "aplapplistitem.h"					// class TApaAppEntry
+#include "aplappinforeader.h"				// class ApaUtils
+
+
+GLDEF_C void Panic(TApfPanic aPanic)
+	{
+	_LIT(KApFilePanic,"APFILE");
+	User::Panic(KApFilePanic,aPanic);
+	}
+
+
+//
+// CApaAppRegFinder
+//
+
+EXPORT_C CApaAppRegFinder* CApaAppRegFinder::NewL(const RFs& aFs)
+	{
+	CApaAppRegFinder* self=NewLC(aFs);
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+EXPORT_C CApaAppRegFinder* CApaAppRegFinder::NewLC(const RFs& aFs)
+	{
+	CApaAppRegFinder* self=new (ELeave) CApaAppRegFinder(aFs);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+	
+CApaAppRegFinder::CApaAppRegFinder(const RFs& aFs)
+	: iFs(aFs),
+	iSidCheckerMap(CApaAppArcServer::Self()?CApaAppArcServer::Self()->RescanCallBack():TCallBack(NULL,NULL))
+	{
+	}
+
+CApaAppRegFinder::~CApaAppRegFinder()
+	{
+	iListOfDrives.Close();
+	iSidCheckerMap.Close();
+	delete iFileList; // should already be deleted and NULL at this point
+	}
+
+void CApaAppRegFinder::ConstructL()
+	{
+	}
+
+
+// Build a list of currently available drives
+void CApaAppRegFinder::RebuildDriveListL(TScanScope aScopeOfScan)
+	{
+	iListOfDrives.Reset();
+	TDriveList driveList;
+	User::LeaveIfError(iFs.DriveList(driveList));
+
+	// Scan through all the drives in the drive list from Y to A, querying the 
+	// file server about wheather the drives are pressent or not
+
+	TInt drive(EDriveY);
+	TDriveUnitInfo driveUnitInfo;
+	while(drive >= EDriveA)
+		{
+		// If the drive exists in the file system...
+		if (driveList[drive]!=KDriveAbsent)
+			{
+			TDriveInfo driveInfo;
+			const TInt err = iFs.Drive(driveInfo, drive);
+			if (!err)
+				{
+				if (aScopeOfScan == EScanRemovableDrives)
+					{// iListOfDrives should have list of all the removable drives irrespective of presence of the media
+					if ((driveInfo.iType != EMediaRemote) && (driveInfo.iDriveAtt & KDriveAttRemovable))
+						{
+						driveUnitInfo.iUnit=drive;
+						driveUnitInfo.iAttribs=driveInfo.iDriveAtt;
+						iListOfDrives.AppendL(driveUnitInfo);
+						}
+					}
+				else // scan all drives
+					{
+					if (driveInfo.iType!=EMediaNotPresent && driveInfo.iType!=EMediaRemote)
+						{
+						driveUnitInfo.iUnit=drive;
+						driveUnitInfo.iAttribs=driveInfo.iDriveAtt;
+						iListOfDrives.AppendL(driveUnitInfo);
+						}
+					}
+				}
+			}
+			
+		--drive;
+		}
+
+	// Add the Z-drive to the list if scanning all drives (not only removable)
+	if (aScopeOfScan == EScanAllDrives)
+		{
+		driveUnitInfo.iUnit=EDriveZ;
+		driveUnitInfo.iAttribs=KDriveAttRom;
+		iListOfDrives.AppendL(driveUnitInfo);
+		}
+	}
+
+EXPORT_C TArray<const TDriveUnitInfo> CApaAppRegFinder::DriveList() const
+	{
+	return iListOfDrives.Array();
+	}
+
+EXPORT_C void CApaAppRegFinder::FindAllAppsL(TScanScope aScopeOfScan)
+	{
+	delete iFileList;
+	iFileList = NULL;
+	RebuildDriveListL(aScopeOfScan);
+	iCurrentIndexInDriveList=-1;
+	iScanStage = EScanStageNonImportROM;
+	iLastChkedApp = KNullUid;	
+	}
+
+/** Scans the applications in following order:
+1. non-import y-a,z but only on ROM drives
+2. import on all non-ROM drives in the order y-a,z
+3. import on all ROM drives in the order y-a,z
+
+Upgrades of apparc server (via Software Install) are currently disallowed. 
+This means it is not possible to install registration files to \private\10003a3f\apps 
+(on any drive), so there is no need to scan \private\10003a3f\apps on non ROM based drives.
+*/
+EXPORT_C TBool CApaAppRegFinder::NextL(TApaAppEntry& aAppRegistrationEntry, const CDesCArray& aForcedRegistrations)
+	{
+	__ASSERT_ALWAYS(iListOfDrives.Count(),Panic(EPanicFindAllAppsNotCalled));
+
+	FOREVER	// Continue until we have looked at all apps on all drives
+		{
+		TDriveUnitInfo currentDrive;
+		TPtrC appFolderOnDrive;
+		
+		if (!iFileList)	// If the file list has been exhausted...
+			{
+			iFileIndex = 0;
+			
+			// Look at the next drive until we find one with applications on it, or we run out of drives.
+			while(NextDriveAndFolderInNormalizedOrder(currentDrive, appFolderOnDrive))	
+				{
+				const TInt err = GetAppListOfDriveL(currentDrive.iUnit, appFolderOnDrive, iFileList);	// ...and create a new list for the next drive.
+				if(!err)	
+					break;	// Found a drive with applications on it
+				}
+				
+			if (!iFileList)		// If we've run out of drives
+				return EFalse; 	// ...then signal this by returning false.
+			}
+		else	// Still apps in the current list. Recall the current drive and path.
+			GetCurrentDriveAndFolder(currentDrive, appFolderOnDrive);
+
+		// Scan the list of all app files for application reg-files
+		while (iFileIndex < iFileList->Count())
+			{
+			const TEntry& entry=(*iFileList)[iFileIndex++];
+			if (!ApaUtils::TypeUidIsForRegistrationFile(entry.iType))
+				continue; // Only interested in app registration resource files
+				
+			// File is application reg-file
+			
+			// Build a parse-object for the full ref-file name
+			TParse regFileNameParser;
+			const TDriveName driveName = currentDrive.iUnit.Name();
+			regFileNameParser.Set(entry.iName, &appFolderOnDrive, &driveName);
+
+			// If the appliation is located on a removable drive...
+			if (currentDrive.iAttribs&KDriveAttRemovable)
+				{
+				// ...then verify that there is a valid Secure ID (SID) for the appliation
+				// to protect against untrusted applications.
+				if (entry[2] != iLastChkedApp) //Check for validity only if it has not yet been checked
+					{
+					const TUid appTypeUid = 
+					(entry[0].iUid == KUidPrefixedNonNativeRegistrationResourceFile ? entry[1] : KNullUid);
+				
+					// Get the CAppSidChecker for this type of executable
+					TBool validRegistration = ETrue;
+					TRAPD(err, validRegistration = iSidCheckerMap.FindSidCheckerL(appTypeUid).AppRegisteredAt(entry[2], currentDrive.iUnit));
+					iLastChkedApp = entry[2];
+					if(!err)
+						{
+						if(!validRegistration)	// If not trusted...
+							{
+							// Check if this registration file should be included despite 
+							// not being officially reported as a valid registration
+							const TPtrC fullName = regFileNameParser.FullName();
+							TInt ignorePos = KErrNotFound;
+							if (aForcedRegistrations.FindIsq(fullName, ignorePos, ECmpFolded) != 0)	// If not found
+								continue;	// App is not trusted. Move on to the next!
+							}
+						// App is trusted! Fall through.
+						}
+					else if(err != KErrNotFound)
+						User::LeaveIfError(err);
+					else
+						continue; // Can't tell. Move on to next.
+					}
+				else
+					{
+					continue;
+					}
+				}
+	
+			// App was found to be trustworthy	
+			aAppRegistrationEntry.iUidType = entry.iType;
+			aAppRegistrationEntry.iFullName = regFileNameParser.FullName();
+			return ETrue;	// Break out of the loop!
+			}
+			
+		// Current drive has been exhausted...
+		delete iFileList;
+		iFileList = NULL;
+		} // ...loop and check the next drive for apps.
+	}
+	
+void CApaAppRegFinder::GetCurrentDriveAndFolder(TDriveUnitInfo& aDrive, TPtrC& aAppFolderOnDrive) const
+	{
+	ASSERT(iCurrentIndexInDriveList != KErrNotFound && iCurrentIndexInDriveList < iListOfDrives.Count());
+	aDrive = iListOfDrives[iCurrentIndexInDriveList];
+	aAppFolderOnDrive.Set(iFolderOnCurrentDrive);
+	}
+	
+TBool CApaAppRegFinder::NextDriveAndFolderInNormalizedOrder(TDriveUnitInfo& aNextDrive, TPtrC& aAppFolderOnDrive) const
+	{
+_LIT(KAppRegRscSearchPath,"\\private\\10003a3f\\apps\\");
+_LIT(KAppRegRscImportSearchPath,"\\private\\10003a3f\\import\\apps\\");
+_LIT(KAppRegRscImportNonNativeSearchPath,"\\private\\10003a3f\\import\\apps\\NonNative\\Resource\\");
+
+	// Updates iCurrentIndexInDriveList
+	// 
+	TBool foundAnotherDrive = ETrue;
+	FOREVER
+		{
+		iCurrentIndexInDriveList++;	// move to next folder
+		if (iCurrentIndexInDriveList >= iListOfDrives.Count())	// If we reached the end if the drive list...
+			{
+			ASSERT(iScanStage < EScanStageComplete);
+			iCurrentIndexInDriveList = 0;		// ...start over from the beginning of the drive list
+			iScanStage++;						// ...and start looking for drives of the next type
+			}
+		
+		// Get next drive's info
+		const TDriveUnitInfo driveUnitInfo = iListOfDrives[iCurrentIndexInDriveList];
+		
+		// Check if this drive is of the correct type for this next stage
+		switch (iScanStage)
+			{
+			case EScanStageNonImportROM:
+			// Stage 1: Look in the non-import folder on ROM drives
+				if (driveUnitInfo.iAttribs==KDriveAttRom)
+					{
+					aAppFolderOnDrive.Set(KAppRegRscSearchPath);
+					goto done;	// Break out of the loop to return the drive found
+					}
+				break;	// Break and move on to the next drive
+			case EScanStageImportNonROM:	
+			// Stage 2: Look in the import folder for native apps on non-ROM drives
+				if (driveUnitInfo.iAttribs!=KDriveAttRom)
+					{
+					aAppFolderOnDrive.Set(KAppRegRscImportSearchPath);
+					goto done;	// Break out of the loop to return the drive found
+					}
+				break; // Break and move on to the next drive
+			case EScanStageImportNonNativeResourceNonROM:
+			// Stage 3: Look in the import folder for non-native apps on non-ROM drives
+				if (driveUnitInfo.iAttribs!=KDriveAttRom)
+					{
+					aAppFolderOnDrive.Set(KAppRegRscImportNonNativeSearchPath);
+					goto done;	// Break out of the loop to return the drive found
+					}
+				break; // Break and move on to the next drive
+			case EScanStageImportROM:
+			// Stage 4: Look in import folder for native apps on ROM drives
+				if (driveUnitInfo.iAttribs==KDriveAttRom)
+					{
+					aAppFolderOnDrive.Set(KAppRegRscImportSearchPath);
+					goto done;	// Break out of the loop to return the drive found
+					}
+				break; // Break and move on to the next drive
+			case EScanStageImportNonNativeResourceROM:
+			// Stage 5: Look in the import folder for non-native apps on ROM drives
+				if (driveUnitInfo.iAttribs==KDriveAttRom)
+					{
+					aAppFolderOnDrive.Set(KAppRegRscImportNonNativeSearchPath);
+					goto done;	// Break out of the loop to return the drive found
+					}
+				break; // Break and move on to the next drive
+			case EScanStageComplete:
+			// Stage 6: All done!
+				aAppFolderOnDrive.Set(KNullDesC);
+				foundAnotherDrive = EFalse;
+				goto done;
+			default:
+				ASSERT(0);
+				break;	
+			}
+		}
+
+done:		
+	aNextDrive = (foundAnotherDrive) ? iListOfDrives[iCurrentIndexInDriveList] : TDriveUnitInfo();
+	iFolderOnCurrentDrive.Set(aAppFolderOnDrive);	// Remember the folder path for GetCurrentDriveAndFolder()
+	return foundAnotherDrive;
+	}	
+	
+_LIT(KAppRegRscSearchAnyFile,"*");
+
+TInt CApaAppRegFinder::GetAppListOfDriveL(TDriveUnit aDriveUnit, const TDesC& aPath, CDir*& aFileList) const
+	{
+	const TDriveName driveName = aDriveUnit.Name();
+	TParse regFileNameParser;
+	TInt error = regFileNameParser.Set(KAppRegRscSearchAnyFile, &aPath, &driveName);
+	User::LeaveIfError(error);
+	
+	ASSERT(!aFileList);
+	error = iFs.GetDir(regFileNameParser.FullName(), KEntryAttAllowUid, ESortNone, aFileList);
+	LeaveIfIrregularErrorL(error);
+	return error;
+	}
+
+void CApaAppRegFinder::LeaveIfIrregularErrorL(TInt aError)	// e.g. KErrNoMemory
+// static
+	{
+	if (aError!=KErrNone && aError!=KErrNotFound && aError!=KErrPathNotFound && aError!=KErrNotReady
+		&& aError!=KErrDisMounted && aError!=KErrCorrupt && aError!=KErrNotSupported && 
+		aError!=KErrBadName && aError!=KErrLocked)
+		{
+		User::Leave(aError);
+		}
+	}