--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/chkdeps/chkdeps.cpp Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,760 @@
+// Copyright (c) 1997-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:
+// Accenture - adapted for fshell, much functionality added
+//
+// Description:
+// Based on \SF\OS\KERNELHWSRV\USERLIBANDFILESERVER\FILESERVER\etshell\ts_deps.cpp
+//
+
+#include "chkdeps.h"
+
+CCommandBase* CDllChecker::NewLC()
+ {
+ CDllChecker* self = new(ELeave) CDllChecker();
+ CleanupStack::PushL(self);
+ self->BaseConstructL();
+ return self;
+ }
+
+const TDesC& CDllChecker::Name() const
+ {
+ _LIT(KName, "chkdeps");
+ return KName;
+ }
+
+void CDllChecker::DoRunL()
+ {
+#ifdef __WINS__
+ PrintWarning(_L("chkdeps only works on E32 (ie ARM) format binaries, not WINS ones"));
+#endif
+ FsL();
+ ConstructL();
+ TBool exists = EFalse;
+ {
+ TEntry e;
+ if (Fs().Entry(iFilename, e) == KErrNone) exists = ETrue;
+ }
+
+ if (!exists)
+ {
+ // Try and resolve
+ iFilename = iFilename.NameAndExt(); // Is this going to work? Assigning to a descriptor a TPtrC that points to itself...?
+ FindDll(iFilename, iFilename, _L("\\sys\\bin\\"));
+ }
+
+ TInt result;
+ iStackBase = &result;
+ iExeInfo = new(ELeave) CDllInfo;
+ iExeInfo->iDllCaps.SetEmpty();
+ iRequiredCaps = &iExeInfo->iDllCaps;
+ TRAP(result, GetImportDataL(iFilename, *iExeInfo));
+ if (result==KErrGeneral)
+ {
+ PrintError(result, _L("%S has no import data"), &iFilename);
+ return;
+ }
+ else if (result)
+ {
+ PrintError(result, _L("Couldn't read %S"), &iFilename);
+ User::Leave(result);
+ }
+ ListArray(); // Print out the results of DllCheck
+ //Stdin().ReadKey();
+ }
+
+void CDllChecker::ArgumentsL(RCommandArgumentList& aArguments)
+ {
+ aArguments.AppendFileNameL(iFilename, _L("file_name"));
+ }
+
+void CDllChecker::OptionsL(RCommandOptionList& aOptions)
+ {
+ aOptions.AppendBoolL(iVerbose, _L("verbose"));
+ aOptions.AppendBoolL(iDebug, _L("debug"));
+ }
+
+EXE_BOILER_PLATE(CDllChecker)
+
+///////////////////////////////////////////////////////////////////////
+
+#define __PRINT(t) { if (iDebug) Printf(t);}
+#define __PRINT1(t,a) { if (iDebug) Printf(t,a);}
+#define __PRINT2(t,a,b) { if (iDebug) Printf(t,a,b);}
+#define __PRINTWAIT(t) { if (iDebug) { Printf(t); Stdin().ReadKey();}}
+
+/*
+
+CDllChecker::GetImportDataL(aFilename) reads the Image Header, Import Section
+and all import data for aFilename. If aFilename is a ROM dll, and thus has no
+import data, or if the file contains no import data for some other reason the
+function leaves with KErrGeneral. If a file is compressed, function calls
+appropriate decompression routine to inflate the import data.
+The function then calls GetDllTableL function which
+reads the first import block and enters a "for" loop. The Dll's name and Uid3 are obtained
+from CDllChecker::GetFileNameAndUid(). If the Dll name does not occur in the
+array of previously checked Dlls, CDllChecker::FindDll() is called. If the Dll
+is found,the function then calls CDllChecker::GetImportDataL on the filename acquired by
+GetFileNameAndUid()(recursive call).
+
+If the Dll contains no import data or cannot be found, or if the Uid is invalid,
+the next import is checked.
+
+The Uid3 value is checked by calling CDllChecker::CheckUid. This compares the
+Uid3 value found in the image header of the file, with that found by
+GetFileNameAndUid(). If there are any discrepancies,these are noted.
+
+Each potential import is added to the array to
+indicate its import status.
+
+CDllChecker::ListArray() lists the contents of the array when all imports
+have been checked.
+*/
+
+
+void CDllChecker::ConstructL()
+//
+// Creates an array to hold DLLs referenced by this executable
+//
+ {
+ }
+
+CDllChecker::CDllChecker()
+ {
+ }
+
+CDllChecker::~CDllChecker()
+//
+// Destructor
+//
+ {
+ iDllArray.ResetAndDestroy();
+ delete iExeInfo;
+ }
+
+void FileCleanup(TAny* aPtr)
+ {
+ TFileInput* f=(TFileInput*)aPtr;
+ f->Cancel();
+ delete f;
+ }
+
+void CDllChecker::LoadFileInflateL(const E32ImageHeaderComp* aHeader, RBuf8& aCode, RBuf8& aRestOfFile)
+ {
+ TInt pos = aHeader->TotalSize();
+ User::LeaveIfError(iFile.Seek(ESeekStart,pos)); // Start at beginning of compressed data
+
+ TFileInput* file = new (ELeave) TFileInput(iFile);
+ CleanupStack::PushL(TCleanupItem(&FileCleanup,file));
+ CInflater* inflater=CInflater::NewLC(*file);
+
+ if (aHeader->iCodeSize)
+ {
+ aCode.CreateL(aHeader->iCodeSize);
+ TInt count = inflater->ReadL((TUint8*)aCode.Ptr(), aHeader->iCodeSize, &Mem::Move);
+ if(count != aHeader->iCodeSize)
+ User::Leave(KErrCorrupt);
+ aCode.SetLength(count);
+ }
+
+ // Compressed executable
+ // iCodeOffset = header size for format V or above
+ // = sizeof(E32ImageHeader) for format J
+ TInt restOfFileSize = aHeader->UncompressedFileSize() - aHeader->iCodeOffset - aHeader->iCodeSize; // the size of the exe less header & code
+
+ if (restOfFileSize)
+ {
+ aRestOfFile.CreateL(restOfFileSize);
+ TUint32 count = inflater->ReadL((TUint8*)aRestOfFile.Ptr(), restOfFileSize, &Mem::Move);
+ if(count != restOfFileSize)
+ User::Leave(KErrCorrupt);
+ aRestOfFile.SetLength(count);
+ }
+ CleanupStack::PopAndDestroy(2,file);
+ }
+
+void CDllChecker::LoadFileNoCompressL(const E32ImageHeaderComp* aHeader, RBuf8& aCode, RBuf8& aRestOfFile)
+ {
+ TInt codepos = aHeader->TotalSize();
+ if (aHeader->iCodeSize)
+ {
+ aCode.CreateL(aHeader->iCodeSize);
+ User::LeaveIfError(iFile.Read(codepos, aCode, aHeader->iCodeSize));
+ }
+
+ TInt restpos = aHeader->TotalSize() + aHeader->iCodeSize;
+ TInt fileSize;
+ User::LeaveIfError(iFile.Size(fileSize));
+ TInt restOfFileSize = fileSize - aHeader->TotalSize() - aHeader->iCodeSize; // the size of the exe less header & code
+
+ if (restOfFileSize)
+ {
+ aRestOfFile.CreateL(restOfFileSize);
+ User::LeaveIfError(iFile.Read(restpos, aRestOfFile, restOfFileSize));
+ }
+ }
+
+void CDllChecker::LoadFileBytePairL(const E32ImageHeaderComp* aHeader, RBuf8& aCode, RBuf8& aRestOfFile)
+ {
+ TInt pos = aHeader->TotalSize();
+ User::LeaveIfError(iFile.Seek(ESeekStart,pos)); // Start at beginning of compressed data
+
+ CBytePairReader* reader = CBytePairFileReader::NewLC(iFile);
+
+ if (aHeader->iCodeSize)
+ {
+ aCode.CreateL(aHeader->iCodeSize);
+ TUint32 bytes = reader->DecompressPagesL((TUint8*)aCode.Ptr(), aHeader->iCodeSize, &Mem::Move);
+ if((TInt)bytes != aHeader->iCodeSize)
+ User::Leave(KErrCorrupt);
+ aCode.SetLength(bytes);
+ }
+
+ TInt restOfFileSize = ((E32ImageHeaderV*)aHeader)->iUncompressedSize - aHeader->iCodeOffset - aHeader->iCodeSize;
+
+ if (restOfFileSize)
+ {
+ aRestOfFile.CreateL(restOfFileSize);
+ TUint32 count = reader->DecompressPagesL((TUint8*)aRestOfFile.Ptr(), restOfFileSize, &Mem::Move);
+ if(count != restOfFileSize)
+ User::Leave(KErrCorrupt);
+ aRestOfFile.SetLength(count);
+ }
+
+ CleanupStack::PopAndDestroy(reader);
+ }
+
+//function loads file's import information calling decompression routine if needed
+void CDllChecker::LoadFileL(const E32ImageHeaderComp* aHeader, RBuf8& aCode, RBuf8& aRestOfFile)
+ {
+ TUint32 aCompression = aHeader->CompressionType();
+
+ if(aCompression==KFormatNotCompressed)
+ {
+ LoadFileNoCompressL(aHeader, aCode, aRestOfFile);
+ }
+ else if(aCompression==KUidCompressionDeflate)
+ {
+ LoadFileInflateL(aHeader, aCode, aRestOfFile);
+ }
+ /*TOMSCI TODO doesn't seem to work...
+ else if (aCompression == KUidCompressionBytePair)
+ {
+ LoadFileBytePairL(aHeader, aCode, aRestOfFile);
+ }*/
+ else
+ {
+ LeaveIfErr(KErrNotSupported, _L("Compression type 0x%x is not supported"), aCompression);
+ }
+ }
+
+
+TBool CDllChecker::CompareDllInfo(const CDllInfo& aDllInfo1, const CDllInfo& aDllInfo2)
+ {
+ return (aDllInfo1.iDllName.CompareF(aDllInfo2.iDllName) == 0);
+ }
+
+
+//function iterates through the list of libraries the current executable depends on
+//for each dependency in the list the function checks whether the .dll being checked is already added to the array of dependencies
+//if not, the function adds dependency being checked to the array of dependencies and calls GetImportDataL function recursively
+//void CDllChecker::GetDllTableL(TUint8* aImportData, TInt aDllRefTableCount,TUint aFlags)
+//void CDllChecker::GetDllTableL(const TDesC& aFileName, E32ImageHeader* aImageHeader, TUint8* aRestOfFile)
+void CDllChecker::GetDllTableL(const TDesC& aFileName, const E32ImageHeader* aImageHeader, const TUint8* aCode, const TUint8* aImportData)
+ {
+ const TInt aDllRefTableCount = aImageHeader->iDllRefTableCount;
+ const TUint aFlags = aImageHeader->iFlags;
+
+ const E32ImportBlock* block = (const E32ImportBlock*)(aImportData+sizeof(E32ImportSection));
+
+ for (TInt i=0; i<aDllRefTableCount; i++)
+ {
+ CDllInfo* dllInfo = new(ELeave) CDllInfo;
+ CleanupStack::PushL(dllInfo);
+ dllInfo->iResult = EPending;
+ dllInfo->iNumExports = 0;
+ const TText8* dllName=(aImportData+block->iOffsetOfDllName);
+ TPtrC8 dllNamePtr(dllName, User::StringLength(dllName));
+ GetFileNameAndUid(*dllInfo,dllNamePtr);
+ __PRINT1(_L("Considering \"%S\"...\r\n"),&dllInfo->iDllName);
+ TInt r=iDllArray.Find(dllInfo,TIdentityRelation<CDllInfo>(CompareDllInfo));
+ if (r >= 0)
+ {
+ __PRINT(_L("\tAlready checked\r\n"));
+ CDllInfo* dllInfoPtr = iDllArray[r];
+ if ((dllInfoPtr->iResult!=EPending) && (dllInfoPtr->iUid!=dllInfo->iUid))
+ {
+ __PRINT2(_L(" Uid3 [%08x] for %S is different from that noted previously\r\n"),dllInfo->iUid,&dllInfo->iDllName);
+ dllInfoPtr->iResult=EUidDifference;
+ }
+ CleanupStack::PopAndDestroy(dllInfo);
+ dllInfo = dllInfoPtr;
+ }
+ else
+ {
+ __PRINT(_L("\tNot previously checked\r\n"));
+ iDllArray.AppendL(dllInfo);
+ CleanupStack::Pop(dllInfo);
+
+ TFileName fileName;
+ r=FindDll(dllInfo->iDllName,fileName,Env().Pwd());
+
+ if (r==KErrNotFound) // Could not find Dll
+ {
+ dllInfo->iResult=ENotFound;
+ }// Run to the end of the "for" loop for this i value
+
+ else // File was located
+ {
+ // Go recursive. Call GetImportDataL on the new dll, if it imports anything.
+ // ROM dlls have no import data so this is never called for ROM dlls.
+ // This *will* terminate. It is only called on "new" dlls not in the array.
+ iCalls++;
+
+ TRAP(r,GetImportDataL(fileName, *dllInfo));
+ switch(r)
+ {
+ case(KErrGeneral): // No import data
+ {
+ dllInfo->iResult=ENoImportData;
+ if (!dllInfo->iDllCaps.HasCapabilities(*iRequiredCaps)) dllInfo->iResult = ERequiredCapabilitiesMissing;
+ break;
+ }
+ case(EUidNotSupported):
+ case(EVersionMismatch):
+ {
+ dllInfo->iResult=(CDllChecker::TResultCheck)r;
+ break;
+ }
+ case(KErrNone): // Import data was read
+ {
+ dllInfo->iResult=EFileFoundAndUidSupported;
+ if (!dllInfo->iDllCaps.HasCapabilities(*iRequiredCaps)) dllInfo->iResult = ERequiredCapabilitiesMissing;
+ break;
+ }
+ case(KErrInUse):
+ {
+ __PRINT2(_L("\t\"%S\" is already open\r\n"),&fileName,r);
+ dllInfo->iResult=EAlreadyOpen;
+ break;
+ }
+ case(KErrCorrupt):
+ {
+ __PRINT2(_L("\t\"%S\" has unexpected format\r\n"),&fileName,r);
+ dllInfo->iResult=EAlreadyOpen;
+ break;
+ }
+ default:
+ {
+ __PRINT1(_L("\t\"%S\" could not be opened \r\n"),&fileName);
+ dllInfo->iResult=ECouldNotOpenFile;
+ break;
+ }
+ }
+ }
+ }
+
+ if (dllInfo->iResult == EFileFoundAndUidSupported)
+ {
+ // Check all the ordinals we import actually exist
+ for (TInt i = 0; i < block->iNumberOfImports; i++)
+ {
+ TInt ordinal = 0;
+ //Printf(_L("we import %d from %S\r\n"), block->Imports()[i], &dllInfo->iDllName);
+ if (aImageHeader->ImportFormat() == KImageImpFmt_ELF)
+ {
+ TUint impd_offset = block->Imports()[i];
+ TUint impd = *(TUint*)(aCode + impd_offset);
+ ordinal = impd & 0xffff;
+ //TUint offset = impd >> 16;
+ }
+ else
+ {
+ ordinal = block->Imports()[i];
+ }
+ //Printf(_L("We import %d (numExports=%d)\r\n"), ordinal, dllInfo->iNumExports);
+ if (ordinal > dllInfo->iNumExports && dllInfo->iResult != ENotFound)
+ {
+ Printf(_L("\tOrdinal %d is missing from \"%S\" (used by \"%S\")\r\n"), ordinal, &dllInfo->iDllName, &aFileName);
+ dllInfo->iResult = EOrdinalMissing;
+ }
+ }
+ }
+ block = (E32ImportBlock*)block->NextBlock(E32ImageHeader::ImpFmtFromFlags(aFlags));
+ }
+ }
+
+
+void CDllChecker::GetImportDataL(const TDesC& aFileName, CDllInfo& aInfo)
+ {
+ TInt cleanupCount=0;
+ // Check that the file is not a ROM dll. These have no import data
+ if (Fs().IsFileInRom(aFileName))
+ {
+ // Still need to fill in caps and export count
+ TRomImageHeader* romHeader = (TRomImageHeader*)Fs().IsFileInRom(aFileName);
+ aInfo.iDllCaps.SetEmpty();
+ SCapabilitySet* caps = &romHeader->iS.iCaps;
+ aInfo.iDllCaps = *(TCapabilitySet*)caps;
+ aInfo.iNumExports = romHeader->iExportDirCount;
+ User::Leave(KErrGeneral);
+ }
+
+ //open file for reading and push it to autoclose stack
+ TAutoClose<RFile> autoFile;
+ User::LeaveIfError(autoFile.iObj.Open(Fs(),aFileName,EFileShareReadersOnly));
+ autoFile.PushL();
+ cleanupCount++;
+ iFile=autoFile.iObj;
+
+ //Create a pointer to an Image Header
+ //reserve enough memory for compressed file header because we don't know whether the file is compressed or not
+ // In fact, allow for a E32ImageHeaderV so we can get the capability info too
+ E32ImageHeaderV* imageHeader=new(ELeave)E32ImageHeaderV;
+ CleanupStack::PushL(imageHeader);
+ cleanupCount++;
+
+ //read file header
+ TPtr8 ptrToImageHeader((TText8*)(imageHeader),sizeof(E32ImageHeaderV),sizeof(E32ImageHeaderV));
+ User::LeaveIfError(iFile.Read(ptrToImageHeader,sizeof(E32ImageHeaderV)));
+
+
+ aInfo.iDllCaps.SetEmpty();
+ if (imageHeader->HeaderFormat() >= KImageHdrFmt_V)
+ {
+ SCapabilitySet* caps = &imageHeader->iS.iCaps;
+ aInfo.iDllCaps = *(TCapabilitySet*)caps;
+ }
+ aInfo.iNumExports = imageHeader->iExportDirCount;
+
+ if (imageHeader->iImportOffset==0) // File contains no import data (ROM files never have import data)
+ {
+ User::Leave(KErrGeneral);
+ }
+
+ RBuf8 code, rest;
+ CleanupClosePushL(code);
+ CleanupClosePushL(rest);
+ cleanupCount += 2;
+ LoadFileL(imageHeader, code, rest); // Read import information in
+
+ TInt32 uid3=imageHeader->iUid3;
+ if(iCalls!=0) // Only check Uid3 of dependencies (ie only after first
+ { // call of recursive function)
+ TInt r=CheckUid3(uid3,aInfo.iUid);
+
+ if (r!=KErrNone) // Dll's Uid3 is not valid
+ User::Leave(EUidNotSupported);
+
+ TInt version = (imageHeader->iModuleVersion >> 16);
+ if (version != aInfo.iMajorVersion)
+ {
+ Printf(_L("Version mismatch - %S version is %d, expected %d\r\n"), &aFileName, version, aInfo.iMajorVersion);
+ User::Leave(EVersionMismatch);
+ }
+ }
+
+ TInt importOffset = imageHeader->iImportOffset - (imageHeader->iCodeOffset + imageHeader->iCodeSize);
+ if (TInt(importOffset + sizeof(E32ImportSection)) > rest.Size())
+ User::Leave(KErrCorrupt);
+ //get the table of dependencies
+ //GetDllTableL(restOfFileData+bufferOffset,imageHeader->iDllRefTableCount,imageHeader->iFlags);
+ //GetDllTableL(aFileName, imageHeader, restOfFileData);
+ GetDllTableL(aFileName, imageHeader, code.Ptr(), rest.Ptr() + importOffset);
+
+ CleanupStack::PopAndDestroy(cleanupCount);
+ }
+
+
+TUint8* CDllChecker::NextBlock(TUint8* aBlock)
+ {
+ E32ImportBlock* block;
+ // Advance the pointer to the next block
+ block=(E32ImportBlock*)aBlock;
+ aBlock=(aBlock+sizeof(E32ImportBlock)+((block->iNumberOfImports)*sizeof(TUint)));
+ return (aBlock);
+ }
+
+
+TFileNameInfo::TFileNameInfo()
+ {
+ memclr(this, sizeof(TFileNameInfo));
+ }
+
+TInt TFileNameInfo::Set(const TDesC8& aFileName, TUint aFlags)
+ {
+ iUid = 0;
+ iVersion = 0;
+ iPathPos = 0;
+ iName = aFileName.Ptr();
+ iLen = aFileName.Length();
+ iExtPos = aFileName.LocateReverse('.');
+ if (iExtPos<0)
+ iExtPos = iLen;
+ TInt osq = aFileName.LocateReverse('[');
+ TInt csq = aFileName.LocateReverse(']');
+ if (!(aFlags & EAllowUid) && (osq>=0 || csq>=0))
+ {
+ return KErrBadName;
+ }
+ if (osq>=iExtPos || csq>=iExtPos)
+ {
+ return KErrBadName;
+ }
+ TInt p = iExtPos;
+ if ((aFlags & EAllowUid) && p>=10 && iName[p-1]==']' && iName[p-10]=='[')
+ {
+ TPtrC8 uidstr(iName + p - 9, 8);
+ TLex8 uidlex(uidstr);
+ TUint32 uid = 0;
+ TInt r = uidlex.Val(uid, EHex);
+ if (r==KErrNone && uidlex.Eos())
+ iUid = uid, p -= 10;
+ }
+ iUidPos = p;
+ TInt ob = aFileName.LocateReverse('{');
+ TInt cb = aFileName.LocateReverse('}');
+ if (ob>=iUidPos || cb>=iUidPos)
+ {
+ return KErrBadName;
+ }
+ if (ob>=0 && cb>=0 && p-1==cb)
+ {
+ TPtrC8 p8(iName, p);
+ TInt d = p8.LocateReverse('.');
+ TPtrC8 verstr(iName+ob+1, p-ob-2);
+ TLex8 verlex(verstr);
+ if (ob==p-10 && d<ob)
+ {
+ TUint32 ver = 0;
+ TInt r = verlex.Val(ver, EHex);
+ if (r==KErrNone && verlex.Eos())
+ iVersion = ver, p = ob;
+ }
+ else if (d>ob && p-1>d && (aFlags & EAllowDecimalVersion))
+ {
+ TUint32 maj = 0;
+ TUint32 min = 0;
+ TInt r = verlex.Val(maj, EDecimal);
+ TUint c = (TUint)verlex.Get();
+ TInt r2 = verlex.Val(min, EDecimal);
+ if (r==KErrNone && c=='.' && r2==KErrNone && verlex.Eos() && maj<32768 && min<32768)
+ iVersion = (maj << 16) | min, p = ob;
+ }
+ }
+ iVerPos = p;
+ if (iLen>=2 && iName[1]==':')
+ {
+ TUint c = iName[0];
+ if (c!='?' || !(aFlags & EAllowPlaceholder))
+ {
+ c |= 0x20;
+ if (c<'a' || c>'z')
+ {
+ return KErrBadName;
+ }
+ }
+ iPathPos = 2;
+ }
+ TPtrC8 pathp(iName+iPathPos, iVerPos-iPathPos);
+ if (pathp.Locate('[')>=0 || pathp.Locate(']')>=0 || pathp.Locate('{')>=0 || pathp.Locate('}')>=0 || pathp.Locate(':')>=0)
+ {
+ return KErrBadName;
+ }
+ iBasePos = pathp.LocateReverse('\\') + 1 + iPathPos;
+ return KErrNone;
+ }
+
+void TFileNameInfo::GetName(TDes8& aName, TUint aFlags) const
+ {
+ if (aFlags & EIncludeDrive)
+ aName.Append(Drive());
+ if (aFlags & EIncludePath)
+ {
+ if (PathLen() && iName[iPathPos]!='\\')
+ aName.Append('\\');
+ aName.Append(Path());
+ }
+ if (aFlags & EIncludeBase)
+ aName.Append(Base());
+ if ((aFlags & EForceVer) || ((aFlags & EIncludeVer) && VerLen()) )
+ {
+ aName.Append('{');
+ aName.AppendNumFixedWidth(iVersion, EHex, 8);
+ aName.Append('}');
+ }
+ if ((aFlags & EForceUid) || ((aFlags & EIncludeUid) && UidLen()) )
+ {
+ aName.Append('[');
+ aName.AppendNumFixedWidth(iUid, EHex, 8);
+ aName.Append(']');
+ }
+ if (aFlags & EIncludeExt)
+ aName.Append(Ext());
+ }
+
+
+void CDllChecker::GetFileNameAndUid(CDllInfo &aDllInfo, const TDesC8 &aExportName)
+//
+// Gets filename and UID
+//
+ {
+ TFileNameInfo filename;
+ filename.Set(aExportName,TFileNameInfo::EAllowUid|TFileNameInfo::EAllowDecimalVersion);
+ TBuf8<KMaxFileName> narrowDllName;
+ filename.GetName(narrowDllName,TFileNameInfo::EIncludeBaseExt);
+ aDllInfo.iDllName.Copy(narrowDllName);
+ aDllInfo.iUid=TUid::Uid(filename.Uid());
+ TUint32 version = filename.Version();
+ aDllInfo.iMajorVersion = version >> 16;
+ aDllInfo.iMinorVersion = version & 0xFFFF;
+ }
+
+
+TInt CDllChecker::CheckUid3(TInt32 aUid3,TUid aUid)
+//
+// Check that Uid3 is the same in the iDllName and as noted by the Image Header
+// aUid3 is the value found by the image header
+// aUid is the value found by parsing the result of block->dllname
+// using GetFileNameAndUid()
+ {
+
+ if ((aUid.iUid)==aUid3)
+ {
+
+ __PRINT(_L("\tUid3 is valid\r\n"));
+ return KErrNone;
+ }
+ else
+ {
+
+ __PRINT(_L("\tUid3 value is not supported\r\n"));
+ return (EUidNotSupported);
+ }
+ }
+
+
+
+TInt CDllChecker::FindDll(TDes& aDllName,TFileName& aFileName, const TDesC& aPath)
+//
+// Search for a dll in the following sequence ...
+// 1. Supplied path parameter
+// 2. System directories on all drives
+//
+ {
+ TFindFile findFile(Fs());
+ TInt r=findFile.FindByPath(aDllName,&aPath);
+ if (r==KErrNone)
+ {
+ aFileName=findFile.File();
+
+ __PRINT1(_L("\t\"%S\" was found (supplied path)\r\n"),&aFileName);
+
+ return(r);
+ }
+
+ r=findFile.FindByDir(aDllName,_L("Y:\\Sys\\Bin\\"));
+ if (r==KErrNone)
+ {
+ aFileName=findFile.File();
+
+ __PRINT1(_L("\t\"%S\" was found (system directory)\r\n"),&aFileName);
+
+ return(r);
+ }
+ /*
+ if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
+ {
+ r=findFile.FindByDir(aDllName,_L("\\System\\Bin\\"));
+ if (r==KErrNone)
+ {
+ aFileName=findFile.File();
+
+ __PRINT1(_L("\t\"%S\" was found (system directory)\r\n"),&aFileName);
+
+ return(r);
+ }
+ }
+ */
+ __PRINT1(_L("\t\"%S\" was not found\r\n"),&aDllName);
+
+ return(KErrNotFound);
+ }
+
+void CDllChecker::ListArray()
+ {
+ const TInt elements=iDllArray.Count();
+
+ Printf(_L("Number of dependencies checked = %d\r\n"),elements);
+
+ for (TInt i=0;i<elements; i++)
+ {
+ CDllInfo& info = *(iDllArray[i]);
+ TResultCheck res = info.iResult;
+ TBool print = iVerbose || (res != EFileFoundAndUidSupported && res != ENoImportData && res != EAlreadyOpen);
+ if (print) Printf(_L("% 2d: %-15S Uid3: [%08x] "),(i+1),&info.iDllName,(info.iUid));
+ if (!print) continue;
+ switch(res)
+ {
+ case(ENoImportData):
+ Printf(_L("--- No import data\r\n"));
+ break;
+
+ case(EUidNotSupported):
+ Printf(_L("--- Uid3 is not supported\r\n"));
+ break;
+
+ case(ENotFound):
+ Printf(_L("--- File was not found\r\n"));
+ break;
+
+ case(ECouldNotOpenFile):
+ Printf(_L("--- File could not be opened\r\n"));
+ break;
+
+ case(EUidDifference):
+ Printf(_L("--- File already noted with different Uid\r\n"));
+ break;
+
+ case(EAlreadyOpen):
+ Printf(_L("--- File already open\r\n"));
+ break;
+
+ case(EFileFoundAndUidSupported):
+ Printf(_L("--- File was found, Uid3 is supported\r\n"));
+ break;
+
+ case ERequiredCapabilitiesMissing:
+ {
+ Printf(_L("--- Dll is missing capabilities:"));
+ for (TInt i = 0; i < ECapability_Limit; i++)
+ {
+ TCapability c = (TCapability)i;
+ if (iRequiredCaps->HasCapability(c) && !info.iDllCaps.HasCapability(c))
+ {
+ Printf(_L8(" %s"), CapabilityNames[i]);
+ }
+ }
+ Printf(_L("\r\n"));
+ break;
+ }
+ case EOrdinalMissing:
+ Printf(_L("--- Required ordinal(s) missing\r\n"));
+ break;
+ case EVersionMismatch:
+ Printf(_L("--- Version mismatch\r\n"));
+ break;
+ default: // Will never reach here
+ Printf(_L("--- Undefined\r\n"));
+ break;
+ }
+ }
+ }