userlibandfileserver/fileserver/sfile/sf_image.h
changeset 0 a41df078684a
child 33 0173bcd7697c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_image.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,347 @@
+// Copyright (c) 1998-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_image.h
+// 
+//
+
+#ifndef __SF_IMAGE_H__
+#define __SF_IMAGE_H__
+#include <f32file.h>
+#include <f32image.h>
+#include <e32ldr.h>
+#include <e32rom.h>
+#include "sf_deflate.h"
+
+_LIT(KLitLoader,"LOADER");
+//__DATA_CAGING__
+const TUint32	KCapabilityOffSet	=	0x18;
+const TUint32	KCapabilityLength	=	0x04;
+const TUint32	KCapabilityMask		=	0x00000001;
+
+enum TPanic
+	{
+	ELoadLibraryWithoutDllLock=0,
+	};
+
+class E32Image;
+class RImageArray : public RPointerArray<E32Image>
+	{
+public:
+	RImageArray();
+	TInt Add(E32Image* aImage);
+	void Find(const TDesC8& aRootName, TInt& aFirst, TInt& aLast) const;
+	E32Image* Find(const TRomImageHeader* aRomImgHdr) const;
+	};
+
+class TFileNameInfo
+	{
+public:
+	enum	{
+			EIncludeDrive=1,
+			EIncludePath=2,
+			EIncludeBase=4,
+			EIncludeVer=8,
+			EForceVer=16,
+			EIncludeUid=32,
+			EForceUid=64,
+			EIncludeExt=128,
+			EIncludeDrivePath=EIncludeDrive|EIncludePath,
+			EIncludeBaseExt=EIncludeBase|EIncludeExt,
+			EIncludeDrivePathBaseExt=EIncludeDrive|EIncludePath|EIncludeBase|EIncludeExt,
+			};
+	enum	{
+			EAllowUid=1,
+			EAllowPlaceholder=2,
+			EAllowDecimalVersion=4,
+			};
+public:
+	TFileNameInfo();
+	TInt Set(const TDesC8& aFileName, TUint aFlags);
+	void Dump() const;
+public:
+	inline TInt DriveLen() const {return iPathPos;}
+	inline TInt PathLen() const {return iBasePos-iPathPos;}
+	inline TInt BaseLen() const {return iVerPos-iBasePos;}
+	inline TInt VerLen() const {return iUidPos-iVerPos;}
+	inline TInt UidLen() const {return iExtPos-iUidPos;}
+	inline TInt ExtLen() const {return iLen-iExtPos;}
+	inline TPtrC8 Drive() const {return TPtrC8(iName, iPathPos);}
+	inline TPtrC8 Path() const {return TPtrC8(iName+iPathPos, iBasePos-iPathPos);}
+	inline TPtrC8 DriveAndPath() const {return TPtrC8(iName, iBasePos);}
+	inline TPtrC8 Base() const {return TPtrC8(iName+iBasePos, iVerPos-iBasePos);}
+	inline TPtrC8 VerStr() const {return TPtrC8(iName+iVerPos, iUidPos-iVerPos);}
+	inline TPtrC8 UidStr() const {return TPtrC8(iName+iUidPos, iExtPos-iUidPos);}
+	inline TPtrC8 Ext() const {return TPtrC8(iName+iExtPos, iLen-iExtPos);}
+	inline TUint32 Version() const {return iVersion;}
+	inline TUint32 Uid() const {return iUid;}
+	void GetName(TDes8& aName, TUint aFlags) const;
+public:
+	const TText8* iName;
+	TInt iPathPos;
+	TInt iBasePos;
+	TInt iVerPos;
+	TInt iUidPos;
+	TInt iExtPos;
+	TInt iLen;
+	TUint32 iVersion;
+	TUint32 iUid;
+	};
+
+class RLoaderMsg;
+
+// Information used to search for an image file
+class RLdrReq : public TLdrInfo
+	{
+public:
+	RLdrReq();
+	void Close();
+	void Panic(TInt aPanic);
+	TInt CheckForSubstDriveInName();
+	TInt CheckForSubstDrivesInPath();
+	TInt AddFileExtension(const TDesC8& aExt);
+	void Dump(const char* aTitle) const;
+	TInt CheckSecInfo(const SSecurityInfo& aCandidate) const;
+public:
+	HBufC8* iFileName;
+	HBufC8* iCmd;
+	HBufC8* iPath;
+	const RLoaderMsg* iMsg;
+	SCapabilitySet iPlatSecCaps;
+	RThread iClientThread;
+	RProcess iClientProcess;
+	TFileNameInfo iFileNameInfo;
+	E32Image* iImporter;
+	};
+
+class RLoaderFile : public RFile
+	{
+public:
+	inline TBool IsOpen()
+		{ return Session().Handle() && SubSessionHandle(); }
+	};
+
+class TImageInfo
+	{
+public:
+	TUint32 iUid[KMaxCheckedUid];
+	TUint32 iModuleVersion;
+	SSecurityInfo iS;
+	TUint32 iAttr;
+	TUint16 iExportDirCount;
+	TUint8 iExportDescType;
+	TUint8 iNameLength;
+	enum TCacheStatusFlags
+		{
+		EHashChecked = 1,
+		};
+	TUint8 iCacheStatus;
+	// 8-bit name follows (store base+ext only, not version)
+	// export description follows name
+	};
+
+// Information returned by a search for an image file
+class TFileCacheRecord;
+class RImageInfo : public TImageInfo
+	{
+public:
+	RImageInfo();
+	RImageInfo& operator=(const TFileCacheRecord& aRecord);
+	void Close();
+	void Accept(RImageInfo& aInfo);
+	inline TBool FileOpened() { return ((RLoaderFile*)&iFile)->IsOpen(); }
+public:
+	RFile iFile;
+	E32ImageHeader* iHeader;				// header if available
+	TUint8* iFileData;						// file data if it's been loaded
+	TUint32 iFileSize;						// size of loaded data
+	const TRomImageHeader* iRomImageHeader;	// pointer to ROM image header for XIP
+	TUint16 iExportDescSize;
+	const TUint8* iExportDesc;				// points into cache record so only valid during a single directory search
+	TUint8 iNeedHashCheck;					// true if hash check was skipped and must be done at load time
+	};
+
+// Image finder - looks at candidates for a load and remembers the best one
+class RImageFinder
+	{
+public:
+	RImageFinder();
+	TInt Set(const RLdrReq& aReq);
+	void Close();
+	TInt Search();
+	TInt Search(const TDesC8* aPath, TInt aDrive);
+	TInt SearchSingleDir();
+	TInt SearchExisting(const RImageArray& aArray);
+	TInt Try(RImageInfo& aInfo, const TDesC8& aRootName, const TDesC8& aDriveAndPath);
+	void RecordCorruptFile();
+	void SetName(const TDesC8& aRootName, const TDesC8& aDriveAndPath);
+	void Dump(const char* aTitle, TInt aR);
+	void CompareHashL(RImageInfo& aInfo, const TDesC8& aDriveAndPath);
+public:
+	TInt iNameMatches;				// number of files for which name matches
+	TInt iUidFail;					// number of files for which UIDs are incompatible
+	TInt iCapFail;					// number of files for which capabilities/SID are incompatible
+	TInt iMajorVersionFail;			// number of files with lower major version than requested
+	TInt iImportFail;				// number of files which failed import check
+	TUint32 iCurrentVersion;		// version of current best match
+	TPtrC8 iCurrentPath;			// current search directory
+	TUint8 iCurrentDrive;			// current search drive
+	TUint8 iFindExact;
+	TUint8 iNewValid;				// a valid new image has been found
+	const RLdrReq* iReq;
+	E32Image* iExisting;			// pointer to existing image if that is currently the best
+	RImageInfo iNew;				// new image info if that is currently the best
+	TBuf8<KMaxFileName> iNewFileName;	// full path name for new image file
+	TBuf8<KMaxKernelName> iRootName;
+	};
+
+extern RFs gTheLoaderFs;
+extern TAny* gExeCodeSeg;
+extern TUint32 gExeAttr;
+extern TAny* gKernelCodeSeg;
+extern TUint32 gKernelAttr;
+extern TBool gExecutesInSupervisorMode;
+
+TInt GetModuleInfo(RLdrReq& aReq);
+TInt GetInfoFromHeader(const RLoaderMsg& aMsg);
+TInt CheckSystemBin(const TDesC& aThePath);
+TInt LoadProcess(RLdrReq& aReq);
+TInt LoadLibrary(RLdrReq& aReq);
+TInt LoadDeviceDriver(RLdrReq& aReq, TInt aDeviceType);
+TInt LoadLocale(RLdrReq& aReq, TLibraryFunction* aExportsList);
+TInt CheckUids(const TUidType& aUids, const TUidType& aRequestedUids);
+TInt OpenFile8(RFile& aFile, const TDesC8& aName);
+TInt CheckSubstDrive(TDes8& aDest, const TDesC8& aSrc);
+TInt CompareVersions(TUint32 aL, TUint32 aR);
+TInt CheckRequiredImports(E32Image* aImporter, E32Image* aExporter, TInt aAction);
+TInt CheckRequiredImports(E32Image* aImporter, const RImageInfo& aExporter, TInt aAction);
+TInt CheckedCollapse(TDes8& aDest, const TDesC16& aSrc);
+
+
+enum TVersionCompareResult
+	{
+	EVersion_MinorBigger=0,
+	EVersion_Exact,
+	EVersion_MajorBigger,
+	EVersion_MinorSmaller,
+	EVersion_MajorSmaller,
+	};
+
+TInt DetailedCompareVersions(TUint32 aCandidate, TUint32 aRequest);
+TInt DetailedCompareVersions(TUint32 aCandidate, TUint32 aRequest, TUint32 aCurrent, TBool aStrict);
+
+enum TVersionCompareAction
+	{
+	EAction_Skip=0,
+	EAction_CheckLastImport,
+	EAction_CheckImports,
+	EAction_Replace,
+	};
+
+
+
+class E32Image : public TProcessCreateInfo
+	{
+public:
+	E32Image();
+	~E32Image();
+	void Reset();
+
+	TInt Construct(RImageFinder& aFinder);
+	void Construct(const TRomImageHeader& a);
+	TInt OpenFile();
+
+	TBool AlwaysLoaded();
+
+	TInt LoadProcess(const RLdrReq& aReq);
+	TInt LoadCodeSeg(const RLdrReq& aReq);
+	TInt DoLoadCodeSeg(const RLdrReq& aReq, RImageFinder& aFinder);
+	TInt DoLoadCodeSeg(const TRomImageHeader& aRomImgHdr);
+	TInt CheckAlreadyLoaded();
+	TInt CheckRomXIPAlreadyLoaded();
+	TInt ProcessFileName();
+	void GetRomFileName();
+	static TBool TraverseDirs(const TRomDir& aDir, const TRomImageHeader* aHdr, TDes8& aName);
+
+	TInt LoadToRam();
+	TInt LoadFile();
+	TInt LoadFileNoCompress();
+	TInt Read(TUint aPos,TUint8* aDest,TUint aSize,TBool aSvPerms=EFalse);
+	void LoadFileInflateL();
+	void LoadFileBytePairUnpakL();
+	TInt RelocateCode();
+	TInt RelocateExports();
+	TInt LoadAndRelocateData();
+	TInt RelocateSection(E32RelocSection* aSection, TUint32 aLoadAddress);
+	static TUint8* WordCopy(TAny* aDestination, const TAny* aSource, TInt aNumberOfBytes);
+	static TUint8* MemCopy(TAny* aDestination, const TAny* aSource, TInt aNumberOfBytes);
+	TInt ReadImportData();
+
+	TInt ProcessImports();
+
+	TInt LoadDlls(RImageArray& aDllArray);
+	TInt GetCurrentImportList(const E32ImportBlock* aBlock);
+	static TInt FixupDlls(RImageArray& aDllArray);
+	TUint64* ExpandFixups(TInt aNumFixups);
+	TInt FinaliseDlls(RImageArray& aDllArray);
+	void CleanupDlls(RImageArray& aDllArray);
+
+	TInt LastCurrentImport();
+	void SortCurrentImportList();
+	static TInt Order(const E32Image& aL, const E32Image& aR);
+	TInt ReadExportDirLoad();
+
+	// for demand paging...
+	TInt ShouldBeCodePaged(TBool& aPage);
+	TInt LoadCompressionData();
+	TInt LoadCompressionDataNoCompress();
+	void LoadCompressionDataBytePairUnpakL();
+	TInt BuildCodeBlockMap();
+	TInt AllocateRelocationData(E32RelocSection* aSection, TUint32 aAreaSize, TUint32 aLoadAddress, TUint32*& aProcessedBlock);
+	TInt BuildImportFixupTable();
+public:
+	const TRomImageHeader* iRomImageHeader;
+	E32ImageHeader* iHeader;
+	E32RelocSection* iCodeRelocSection;		// address within iRestOfFileData 
+	E32RelocSection* iDataRelocSection;		// address within iRestOfFileData 
+	TUint32* iImportData;
+	TUint8* iRestOfFileData;				// buffer holding all file data after code section
+	TUint32 iRestOfFileSize;				// size of data at iRestOfFileData
+	TUint32 iConversionOffset;
+	RFile iFile;
+	TUint8* iFileData;						// file data if it's been loaded
+	TUint32 iFileSize;						// size of loaded data
+	TUint32* iCopyOfExportDir;
+	TUint32 iExportDirLoad;
+	TUint32 iExportDirEntryDelta; // value to add to all values read from iExportDirLoad
+	E32Image* iMain;
+	TAny* iCloseCodeSeg;
+	TInt iCurrentImportCount;
+	TInt iNextImportPos;
+	TUint32* iCurrentImportList;
+	TUint8 iCurrentImportListSorted;
+	TUint8 iIsDll;
+	TUint8 iAlreadyLoaded;
+	TUint8 iPadding2;
+	TInt iFixupCount;				// number of fixups in iFixups
+	TUint64* iFixups;				// array of fixups to apply to demand paged code {addr,value} pairs
+	};
+
+
+inline TBool CheckUid(TUint32 aUid, TUint32 aRequestedUid)
+	{
+	return (aRequestedUid==0 || aRequestedUid==aUid);
+	}
+
+
+#endif