commands/chkdeps/chkdeps.cpp
changeset 0 7f656887cf89
child 89 ce94bcf3f672
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // Copyright (c) 1997-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 the License "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 // Accenture - adapted for fshell, much functionality added
       
    13 //
       
    14 // Description:
       
    15 // Based on \SF\OS\KERNELHWSRV\USERLIBANDFILESERVER\FILESERVER\etshell\ts_deps.cpp
       
    16 //
       
    17 
       
    18 #include "chkdeps.h"
       
    19 
       
    20 CCommandBase* CDllChecker::NewLC()
       
    21 	{
       
    22 	CDllChecker* self = new(ELeave) CDllChecker();
       
    23 	CleanupStack::PushL(self);
       
    24 	self->BaseConstructL();
       
    25 	return self;
       
    26 	}
       
    27 
       
    28 const TDesC& CDllChecker::Name() const
       
    29 	{
       
    30 	_LIT(KName, "chkdeps");
       
    31 	return KName;
       
    32 	}
       
    33 
       
    34 void CDllChecker::DoRunL()
       
    35 	{
       
    36 #ifdef __WINS__
       
    37 	PrintWarning(_L("chkdeps only works on E32 (ie ARM) format binaries, not WINS ones"));
       
    38 #endif
       
    39 	FsL();
       
    40 	ConstructL();
       
    41 	TBool exists = EFalse;
       
    42 		{
       
    43 		TEntry e;
       
    44 		if (Fs().Entry(iFilename, e) == KErrNone) exists = ETrue;
       
    45 		}
       
    46 
       
    47 	if (!exists)
       
    48 		{
       
    49 		// Try and resolve
       
    50 		iFilename = iFilename.NameAndExt(); // Is this going to work? Assigning to a descriptor a TPtrC that points to itself...?
       
    51 		FindDll(iFilename, iFilename, _L("\\sys\\bin\\"));
       
    52 		}
       
    53 
       
    54 	TInt result;
       
    55 	iStackBase = &result;
       
    56 	iExeInfo = new(ELeave) CDllInfo;
       
    57 	iExeInfo->iDllCaps.SetEmpty();
       
    58 	iRequiredCaps = &iExeInfo->iDllCaps;
       
    59 	TRAP(result, GetImportDataL(iFilename, *iExeInfo));
       
    60 	if (result==KErrGeneral)
       
    61 		{
       
    62 		PrintError(result, _L("%S has no import data"), &iFilename);
       
    63 		return;
       
    64 		}
       
    65 	else if (result)
       
    66 		{
       
    67 		PrintError(result, _L("Couldn't read %S"), &iFilename);
       
    68 		User::Leave(result);
       
    69 		}
       
    70 	ListArray();	//	Print out the results of DllCheck
       
    71 	//Stdin().ReadKey();
       
    72 	}
       
    73 
       
    74 void CDllChecker::ArgumentsL(RCommandArgumentList& aArguments)
       
    75 	{
       
    76 	aArguments.AppendFileNameL(iFilename, _L("file_name"));
       
    77 	}
       
    78 
       
    79 void CDllChecker::OptionsL(RCommandOptionList& aOptions)
       
    80 	{
       
    81 	aOptions.AppendBoolL(iVerbose, _L("verbose"));
       
    82 	aOptions.AppendBoolL(iDebug, _L("debug"));
       
    83 	}
       
    84 
       
    85 EXE_BOILER_PLATE(CDllChecker)
       
    86 
       
    87 ///////////////////////////////////////////////////////////////////////
       
    88 
       
    89 #define __PRINT(t) { if (iDebug) Printf(t);}
       
    90 #define __PRINT1(t,a) { if (iDebug) Printf(t,a);}
       
    91 #define __PRINT2(t,a,b) { if (iDebug) Printf(t,a,b);}
       
    92 #define __PRINTWAIT(t) { if (iDebug) { Printf(t); Stdin().ReadKey();}}
       
    93 
       
    94 /*
       
    95   
       
    96 CDllChecker::GetImportDataL(aFilename) reads the Image Header, Import Section 
       
    97 and all import data for aFilename.  If aFilename is a ROM dll, and thus has no 
       
    98 import data, or if the file contains no import data for some other reason the 
       
    99 function leaves with KErrGeneral. If a file is compressed, function calls 
       
   100 appropriate decompression routine to inflate the import data.
       
   101 The function then calls GetDllTableL function which 
       
   102 reads the first import block and enters a "for" loop. The Dll's name and Uid3 are obtained 
       
   103 from CDllChecker::GetFileNameAndUid().  If the Dll name does not occur in the 
       
   104 array of previously checked Dlls, CDllChecker::FindDll() is called.  If the Dll 
       
   105 is found,the function then calls CDllChecker::GetImportDataL on the filename acquired by 
       
   106 GetFileNameAndUid()(recursive call). 
       
   107 
       
   108 If the Dll contains no import data or cannot be found, or if the Uid is invalid,
       
   109 the next import is checked.
       
   110 
       
   111 The Uid3 value is checked by calling CDllChecker::CheckUid.  This compares the 
       
   112 Uid3 value found in the image header of the file, with that found by 
       
   113 GetFileNameAndUid().  If there are any discrepancies,these are noted.
       
   114 
       
   115 Each potential import is added to the array to 
       
   116 indicate its import status.
       
   117 
       
   118 CDllChecker::ListArray() lists the contents of the array when all imports
       
   119 have been checked.
       
   120 */
       
   121 
       
   122 
       
   123 void CDllChecker::ConstructL()
       
   124 //
       
   125 //	Creates an array to hold DLLs referenced by this executable	
       
   126 //
       
   127 	{
       
   128 	}
       
   129 
       
   130 CDllChecker::CDllChecker()
       
   131 	{
       
   132 	}
       
   133 
       
   134 CDllChecker::~CDllChecker()
       
   135 //
       
   136 //	Destructor
       
   137 //
       
   138 	{
       
   139     iDllArray.ResetAndDestroy();
       
   140 	delete iExeInfo;
       
   141 	}
       
   142 
       
   143 void FileCleanup(TAny* aPtr)
       
   144 	{
       
   145 	TFileInput* f=(TFileInput*)aPtr;
       
   146 	f->Cancel();
       
   147 	delete f;
       
   148 	}
       
   149 
       
   150 void CDllChecker::LoadFileInflateL(const E32ImageHeaderComp* aHeader, RBuf8& aCode, RBuf8& aRestOfFile)
       
   151 	{
       
   152 	TInt pos = aHeader->TotalSize();
       
   153 	User::LeaveIfError(iFile.Seek(ESeekStart,pos)); // Start at beginning of compressed data
       
   154 
       
   155 	TFileInput* file = new (ELeave) TFileInput(iFile);
       
   156 	CleanupStack::PushL(TCleanupItem(&FileCleanup,file));
       
   157 	CInflater* inflater=CInflater::NewLC(*file);
       
   158 	
       
   159 	if (aHeader->iCodeSize)
       
   160 		{
       
   161 		aCode.CreateL(aHeader->iCodeSize);
       
   162 		TInt count = inflater->ReadL((TUint8*)aCode.Ptr(), aHeader->iCodeSize, &Mem::Move);
       
   163 		if(count != aHeader->iCodeSize)
       
   164 			User::Leave(KErrCorrupt);
       
   165 		aCode.SetLength(count);
       
   166 		}
       
   167 	
       
   168 	// Compressed executable
       
   169 	// iCodeOffset	= header size for format V or above
       
   170 	//				= sizeof(E32ImageHeader) for format J
       
   171 	TInt restOfFileSize = aHeader->UncompressedFileSize() - aHeader->iCodeOffset - aHeader->iCodeSize; // the size of the exe less header & code
       
   172 
       
   173 	if (restOfFileSize)
       
   174 		{
       
   175 		aRestOfFile.CreateL(restOfFileSize);
       
   176 		TUint32 count = inflater->ReadL((TUint8*)aRestOfFile.Ptr(), restOfFileSize, &Mem::Move);
       
   177 		if(count != restOfFileSize)
       
   178 			User::Leave(KErrCorrupt);
       
   179 		aRestOfFile.SetLength(count);
       
   180 		}
       
   181 	CleanupStack::PopAndDestroy(2,file);
       
   182 	}
       
   183 
       
   184 void CDllChecker::LoadFileNoCompressL(const E32ImageHeaderComp* aHeader, RBuf8& aCode, RBuf8& aRestOfFile)
       
   185 	{
       
   186 	TInt codepos = aHeader->TotalSize();
       
   187 	if (aHeader->iCodeSize)
       
   188 		{
       
   189 		aCode.CreateL(aHeader->iCodeSize);
       
   190 		User::LeaveIfError(iFile.Read(codepos, aCode, aHeader->iCodeSize));
       
   191 		}
       
   192 
       
   193 	TInt restpos = aHeader->TotalSize() + aHeader->iCodeSize;
       
   194 	TInt fileSize;
       
   195 	User::LeaveIfError(iFile.Size(fileSize));
       
   196 	TInt restOfFileSize = fileSize - aHeader->TotalSize() - aHeader->iCodeSize; // the size of the exe less header & code
       
   197 
       
   198 	if (restOfFileSize)
       
   199 		{
       
   200 		aRestOfFile.CreateL(restOfFileSize);
       
   201 		User::LeaveIfError(iFile.Read(restpos, aRestOfFile, restOfFileSize));	
       
   202 		}
       
   203 	}
       
   204 
       
   205 void CDllChecker::LoadFileBytePairL(const E32ImageHeaderComp* aHeader, RBuf8& aCode, RBuf8& aRestOfFile)
       
   206 	{
       
   207 	TInt pos = aHeader->TotalSize();
       
   208 	User::LeaveIfError(iFile.Seek(ESeekStart,pos)); // Start at beginning of compressed data
       
   209 
       
   210 	CBytePairReader* reader = CBytePairFileReader::NewLC(iFile);
       
   211 
       
   212 	if (aHeader->iCodeSize)
       
   213 		{
       
   214 		aCode.CreateL(aHeader->iCodeSize);
       
   215 		TUint32 bytes = reader->DecompressPagesL((TUint8*)aCode.Ptr(), aHeader->iCodeSize, &Mem::Move);
       
   216 		if((TInt)bytes != aHeader->iCodeSize)
       
   217 			User::Leave(KErrCorrupt);
       
   218 		aCode.SetLength(bytes);
       
   219 		}
       
   220 
       
   221 	TInt restOfFileSize = ((E32ImageHeaderV*)aHeader)->iUncompressedSize - aHeader->iCodeOffset - aHeader->iCodeSize;
       
   222 
       
   223 	if (restOfFileSize)
       
   224 		{
       
   225 		aRestOfFile.CreateL(restOfFileSize);
       
   226 		TUint32 count = reader->DecompressPagesL((TUint8*)aRestOfFile.Ptr(), restOfFileSize, &Mem::Move);
       
   227 		if(count != restOfFileSize)
       
   228 			User::Leave(KErrCorrupt);
       
   229 		aRestOfFile.SetLength(count);
       
   230 		}
       
   231 
       
   232 	CleanupStack::PopAndDestroy(reader);
       
   233 	}
       
   234 
       
   235 //function loads file's import information calling decompression routine if needed
       
   236 void CDllChecker::LoadFileL(const E32ImageHeaderComp* aHeader, RBuf8& aCode, RBuf8& aRestOfFile)
       
   237 	{
       
   238 	TUint32 aCompression = aHeader->CompressionType();
       
   239 
       
   240 	if(aCompression==KFormatNotCompressed)
       
   241 		{
       
   242 		LoadFileNoCompressL(aHeader, aCode, aRestOfFile);
       
   243 		}
       
   244 	else if(aCompression==KUidCompressionDeflate)
       
   245 		{
       
   246 		LoadFileInflateL(aHeader, aCode, aRestOfFile);
       
   247 		}
       
   248 	/*TOMSCI TODO doesn't seem to work...
       
   249 	else if (aCompression == KUidCompressionBytePair)
       
   250 		{
       
   251 		LoadFileBytePairL(aHeader, aCode, aRestOfFile);
       
   252 		}*/
       
   253 	else
       
   254 		{
       
   255 		LeaveIfErr(KErrNotSupported, _L("Compression type 0x%x is not supported"), aCompression);
       
   256 		}
       
   257 	}
       
   258 
       
   259 
       
   260 TBool CDllChecker::CompareDllInfo(const CDllInfo& aDllInfo1, const CDllInfo& aDllInfo2)
       
   261 	{
       
   262 	return (aDllInfo1.iDllName.CompareF(aDllInfo2.iDllName) == 0);
       
   263 	}
       
   264 
       
   265 								
       
   266 //function iterates through the list of libraries the current executable depends on
       
   267 //for each dependency in the list the function checks whether the .dll being checked is already added to the array of dependencies
       
   268 //if not, the function adds dependency being checked to the array of dependencies and calls GetImportDataL function recursively
       
   269 //void CDllChecker::GetDllTableL(TUint8* aImportData, TInt aDllRefTableCount,TUint aFlags)
       
   270 //void CDllChecker::GetDllTableL(const TDesC& aFileName, E32ImageHeader* aImageHeader, TUint8* aRestOfFile)
       
   271 void CDllChecker::GetDllTableL(const TDesC& aFileName, const E32ImageHeader* aImageHeader, const TUint8* aCode, const TUint8* aImportData)
       
   272 	{
       
   273 	const TInt aDllRefTableCount = aImageHeader->iDllRefTableCount;
       
   274 	const TUint aFlags = aImageHeader->iFlags;
       
   275 
       
   276 	const E32ImportBlock* block = (const E32ImportBlock*)(aImportData+sizeof(E32ImportSection));
       
   277 
       
   278 	for (TInt i=0; i<aDllRefTableCount; i++)	
       
   279 		{
       
   280 		CDllInfo* dllInfo = new(ELeave) CDllInfo;
       
   281 		CleanupStack::PushL(dllInfo);
       
   282 		dllInfo->iResult = EPending;
       
   283 		dllInfo->iNumExports = 0;
       
   284 		const TText8* dllName=(aImportData+block->iOffsetOfDllName);
       
   285 		TPtrC8 dllNamePtr(dllName, User::StringLength(dllName));
       
   286 		GetFileNameAndUid(*dllInfo,dllNamePtr);
       
   287 		__PRINT1(_L("Considering \"%S\"...\r\n"),&dllInfo->iDllName);
       
   288 		TInt r=iDllArray.Find(dllInfo,TIdentityRelation<CDllInfo>(CompareDllInfo));
       
   289 		if (r >= 0)
       
   290 			{
       
   291 			__PRINT(_L("\tAlready checked\r\n"));
       
   292 			CDllInfo* dllInfoPtr = iDllArray[r];
       
   293 			if ((dllInfoPtr->iResult!=EPending) && (dllInfoPtr->iUid!=dllInfo->iUid))	
       
   294 				{
       
   295 				__PRINT2(_L(" Uid3 [%08x] for %S is different from that noted previously\r\n"),dllInfo->iUid,&dllInfo->iDllName);
       
   296 				dllInfoPtr->iResult=EUidDifference;
       
   297 				}
       
   298 			CleanupStack::PopAndDestroy(dllInfo);
       
   299 			dllInfo = dllInfoPtr;
       
   300 			}
       
   301 		else
       
   302 			{
       
   303 			__PRINT(_L("\tNot previously checked\r\n"));
       
   304 			iDllArray.AppendL(dllInfo);
       
   305 			CleanupStack::Pop(dllInfo);
       
   306 		
       
   307 			TFileName fileName;
       
   308 			r=FindDll(dllInfo->iDllName,fileName,Env().Pwd());
       
   309 			
       
   310 			if (r==KErrNotFound)	//	Could not find Dll
       
   311 				{
       
   312 				dllInfo->iResult=ENotFound;
       
   313 				}//	Run to the end of the "for" loop for this i value
       
   314 
       
   315 			else	//	File was located 
       
   316 				{
       
   317 				//	Go recursive.  Call GetImportDataL on the new dll, if it imports anything.
       
   318 				//	ROM dlls have no import data so this is never called for ROM dlls.
       
   319 				//	This *will* terminate.  It is only called on "new" dlls not in the array.
       
   320 				iCalls++;
       
   321 				
       
   322 				TRAP(r,GetImportDataL(fileName, *dllInfo));				
       
   323 				switch(r)		
       
   324 					{
       
   325 					case(KErrGeneral):	//	No import data
       
   326 						{
       
   327 						dllInfo->iResult=ENoImportData;
       
   328 						if (!dllInfo->iDllCaps.HasCapabilities(*iRequiredCaps)) dllInfo->iResult = ERequiredCapabilitiesMissing;
       
   329 						break;
       
   330 						}
       
   331 					case(EUidNotSupported):
       
   332 					case(EVersionMismatch):
       
   333 						{
       
   334 						dllInfo->iResult=(CDllChecker::TResultCheck)r;
       
   335 						break;
       
   336 						}
       
   337 					case(KErrNone):	//	Import data was read
       
   338 						{
       
   339 						dllInfo->iResult=EFileFoundAndUidSupported;
       
   340 						if (!dllInfo->iDllCaps.HasCapabilities(*iRequiredCaps)) dllInfo->iResult = ERequiredCapabilitiesMissing;
       
   341 						break;
       
   342 						}
       
   343 					case(KErrInUse):
       
   344 						{
       
   345 						__PRINT2(_L("\t\"%S\" is already open\r\n"),&fileName,r);
       
   346 						dllInfo->iResult=EAlreadyOpen;
       
   347 						break;
       
   348 						}
       
   349 					case(KErrCorrupt):
       
   350 						{
       
   351 						__PRINT2(_L("\t\"%S\" has unexpected format\r\n"),&fileName,r);
       
   352 						dllInfo->iResult=EAlreadyOpen;
       
   353 						break;
       
   354 						}
       
   355 					default:
       
   356 						{
       
   357 						__PRINT1(_L("\t\"%S\" could not be opened \r\n"),&fileName);
       
   358 						dllInfo->iResult=ECouldNotOpenFile;
       
   359 						break;
       
   360 						}
       
   361 					}	
       
   362 				}
       
   363 			}
       
   364 
       
   365 		if (dllInfo->iResult == EFileFoundAndUidSupported)
       
   366 			{
       
   367 			// Check all the ordinals we import actually exist
       
   368 			for (TInt i = 0; i < block->iNumberOfImports; i++)
       
   369 				{
       
   370 				TInt ordinal = 0;
       
   371 				//Printf(_L("we import %d from %S\r\n"), block->Imports()[i], &dllInfo->iDllName);
       
   372 				if (aImageHeader->ImportFormat() == KImageImpFmt_ELF)
       
   373 					{
       
   374 					TUint impd_offset = block->Imports()[i];
       
   375 					TUint impd = *(TUint*)(aCode + impd_offset);
       
   376 					ordinal = impd & 0xffff;
       
   377 					//TUint offset = impd >> 16;
       
   378 					}
       
   379 				else
       
   380 					{
       
   381 					ordinal = block->Imports()[i];
       
   382 					}
       
   383 				//Printf(_L("We import %d (numExports=%d)\r\n"), ordinal, dllInfo->iNumExports);
       
   384 				if (ordinal > dllInfo->iNumExports && dllInfo->iResult != ENotFound)
       
   385 					{
       
   386 					Printf(_L("\tOrdinal %d is missing from \"%S\" (used by \"%S\")\r\n"), ordinal, &dllInfo->iDllName, &aFileName);
       
   387 					dllInfo->iResult = EOrdinalMissing;
       
   388 					}
       
   389 				}
       
   390 			}
       
   391 		block = (E32ImportBlock*)block->NextBlock(E32ImageHeader::ImpFmtFromFlags(aFlags));
       
   392 		}
       
   393 	}
       
   394 
       
   395 
       
   396 void CDllChecker::GetImportDataL(const TDesC& aFileName, CDllInfo& aInfo)
       
   397 	{
       
   398 	TInt cleanupCount=0;
       
   399 	//	Check that the file is not a ROM dll.  These have no import data	
       
   400 	if (Fs().IsFileInRom(aFileName))
       
   401 		{
       
   402 		// Still need to fill in caps and export count
       
   403 		TRomImageHeader* romHeader = (TRomImageHeader*)Fs().IsFileInRom(aFileName);
       
   404 		aInfo.iDllCaps.SetEmpty();
       
   405 		SCapabilitySet* caps = &romHeader->iS.iCaps;
       
   406 		aInfo.iDllCaps = *(TCapabilitySet*)caps;
       
   407 		aInfo.iNumExports = romHeader->iExportDirCount;
       
   408 		User::Leave(KErrGeneral);
       
   409 		}
       
   410 	
       
   411 	//open file for reading and push it to autoclose stack
       
   412 	TAutoClose<RFile> autoFile;
       
   413 	User::LeaveIfError(autoFile.iObj.Open(Fs(),aFileName,EFileShareReadersOnly));
       
   414 	autoFile.PushL();
       
   415 	cleanupCount++;
       
   416 	iFile=autoFile.iObj;
       
   417 		
       
   418 	//Create a pointer to an Image Header
       
   419 	//reserve enough memory for compressed file header because we don't know whether the file is compressed or not 
       
   420 	// In fact, allow for a E32ImageHeaderV so we can get the capability info too
       
   421 	E32ImageHeaderV* imageHeader=new(ELeave)E32ImageHeaderV;
       
   422 	CleanupStack::PushL(imageHeader);
       
   423 	cleanupCount++;
       
   424 	
       
   425 	//read file header
       
   426 	TPtr8 ptrToImageHeader((TText8*)(imageHeader),sizeof(E32ImageHeaderV),sizeof(E32ImageHeaderV));
       
   427 	User::LeaveIfError(iFile.Read(ptrToImageHeader,sizeof(E32ImageHeaderV)));
       
   428 	
       
   429 
       
   430 	aInfo.iDllCaps.SetEmpty();
       
   431 	if (imageHeader->HeaderFormat() >= KImageHdrFmt_V)
       
   432 		{
       
   433 		SCapabilitySet* caps = &imageHeader->iS.iCaps;
       
   434 		aInfo.iDllCaps = *(TCapabilitySet*)caps;
       
   435 		}
       
   436 	aInfo.iNumExports = imageHeader->iExportDirCount;
       
   437 
       
   438 	if (imageHeader->iImportOffset==0) // File contains no import data (ROM files never have import data)
       
   439 		{	
       
   440 		User::Leave(KErrGeneral);
       
   441 		}
       
   442 
       
   443 	RBuf8 code, rest;
       
   444 	CleanupClosePushL(code);
       
   445 	CleanupClosePushL(rest);
       
   446 	cleanupCount += 2;
       
   447 	LoadFileL(imageHeader, code, rest); // Read import information in
       
   448 			
       
   449 	TInt32 uid3=imageHeader->iUid3;
       
   450 	if(iCalls!=0)	//	Only check Uid3 of dependencies (ie only after first 
       
   451 		{			//	call of recursive function)
       
   452 		TInt r=CheckUid3(uid3,aInfo.iUid);
       
   453 
       
   454 		if (r!=KErrNone) //	Dll's Uid3 is not valid
       
   455 			User::Leave(EUidNotSupported);
       
   456 
       
   457 		TInt version = (imageHeader->iModuleVersion >> 16);
       
   458 		if (version != aInfo.iMajorVersion)
       
   459 			{
       
   460 			Printf(_L("Version mismatch - %S version is %d, expected %d\r\n"), &aFileName, version, aInfo.iMajorVersion);
       
   461 			User::Leave(EVersionMismatch);
       
   462 			}
       
   463 		}
       
   464 
       
   465 	TInt importOffset = imageHeader->iImportOffset - (imageHeader->iCodeOffset + imageHeader->iCodeSize);
       
   466 	if (TInt(importOffset + sizeof(E32ImportSection)) > rest.Size())
       
   467 		User::Leave(KErrCorrupt);		
       
   468 	//get the table of dependencies
       
   469 	//GetDllTableL(restOfFileData+bufferOffset,imageHeader->iDllRefTableCount,imageHeader->iFlags);
       
   470 	//GetDllTableL(aFileName, imageHeader, restOfFileData);
       
   471 	GetDllTableL(aFileName, imageHeader, code.Ptr(), rest.Ptr() + importOffset);
       
   472 
       
   473 	CleanupStack::PopAndDestroy(cleanupCount);	
       
   474 	}
       
   475 
       
   476 
       
   477 TUint8* CDllChecker::NextBlock(TUint8* aBlock)
       
   478 	{
       
   479 	E32ImportBlock* block;	
       
   480 	//	Advance the pointer to the next block	
       
   481 	block=(E32ImportBlock*)aBlock;
       
   482 	aBlock=(aBlock+sizeof(E32ImportBlock)+((block->iNumberOfImports)*sizeof(TUint)));		
       
   483 	return (aBlock);
       
   484 	}
       
   485 
       
   486 
       
   487 TFileNameInfo::TFileNameInfo()
       
   488 	{
       
   489 	memclr(this, sizeof(TFileNameInfo));
       
   490 	}
       
   491 
       
   492 TInt TFileNameInfo::Set(const TDesC8& aFileName, TUint aFlags)
       
   493 	{
       
   494 	iUid = 0;
       
   495 	iVersion = 0;
       
   496 	iPathPos = 0;
       
   497 	iName = aFileName.Ptr();
       
   498 	iLen = aFileName.Length();
       
   499 	iExtPos = aFileName.LocateReverse('.');
       
   500 	if (iExtPos<0)
       
   501 		iExtPos = iLen;
       
   502 	TInt osq = aFileName.LocateReverse('[');
       
   503 	TInt csq = aFileName.LocateReverse(']');
       
   504 	if (!(aFlags & EAllowUid) && (osq>=0 || csq>=0))
       
   505 		{
       
   506 		return KErrBadName;
       
   507 		}
       
   508 	if (osq>=iExtPos || csq>=iExtPos)
       
   509 		{
       
   510 		return KErrBadName;
       
   511 		}
       
   512 	TInt p = iExtPos;
       
   513 	if ((aFlags & EAllowUid) && p>=10 && iName[p-1]==']' && iName[p-10]=='[')
       
   514 		{
       
   515 		TPtrC8 uidstr(iName + p - 9, 8);
       
   516 		TLex8 uidlex(uidstr);
       
   517 		TUint32 uid = 0;
       
   518 		TInt r = uidlex.Val(uid, EHex);
       
   519 		if (r==KErrNone && uidlex.Eos())
       
   520 			iUid = uid, p -= 10;
       
   521 		}
       
   522 	iUidPos = p;
       
   523 	TInt ob = aFileName.LocateReverse('{');
       
   524 	TInt cb = aFileName.LocateReverse('}');
       
   525 	if (ob>=iUidPos || cb>=iUidPos)
       
   526 		{
       
   527 		return KErrBadName;
       
   528 		}
       
   529 	if (ob>=0 && cb>=0 && p-1==cb)
       
   530 		{
       
   531 		TPtrC8 p8(iName, p);
       
   532 		TInt d = p8.LocateReverse('.');
       
   533 		TPtrC8 verstr(iName+ob+1, p-ob-2);
       
   534 		TLex8 verlex(verstr);
       
   535 		if (ob==p-10 && d<ob)
       
   536 			{
       
   537 			TUint32 ver = 0;
       
   538 			TInt r = verlex.Val(ver, EHex);
       
   539 			if (r==KErrNone && verlex.Eos())
       
   540 				iVersion = ver, p = ob;
       
   541 			}
       
   542 		else if (d>ob && p-1>d && (aFlags & EAllowDecimalVersion))
       
   543 			{
       
   544 			TUint32 maj = 0;
       
   545 			TUint32 min = 0;
       
   546 			TInt r = verlex.Val(maj, EDecimal);
       
   547 			TUint c = (TUint)verlex.Get();
       
   548 			TInt r2 = verlex.Val(min, EDecimal);
       
   549 			if (r==KErrNone && c=='.' && r2==KErrNone && verlex.Eos() && maj<32768 && min<32768)
       
   550 				iVersion = (maj << 16) | min, p = ob;
       
   551 			}
       
   552 		}
       
   553 	iVerPos = p;
       
   554 	if (iLen>=2 && iName[1]==':')
       
   555 		{
       
   556 		TUint c = iName[0];
       
   557 		if (c!='?' || !(aFlags & EAllowPlaceholder))
       
   558 			{
       
   559 			c |= 0x20;
       
   560 			if (c<'a' || c>'z')
       
   561 				{
       
   562 				return KErrBadName;
       
   563 				}
       
   564 			}
       
   565 		iPathPos = 2;
       
   566 		}
       
   567 	TPtrC8 pathp(iName+iPathPos, iVerPos-iPathPos);
       
   568 	if (pathp.Locate('[')>=0 || pathp.Locate(']')>=0 || pathp.Locate('{')>=0 || pathp.Locate('}')>=0 || pathp.Locate(':')>=0)
       
   569 		{
       
   570 		return KErrBadName;
       
   571 		}
       
   572 	iBasePos = pathp.LocateReverse('\\') + 1 + iPathPos;
       
   573 	return KErrNone;
       
   574 	}
       
   575 
       
   576 void TFileNameInfo::GetName(TDes8& aName, TUint aFlags) const
       
   577 	{
       
   578 	if (aFlags & EIncludeDrive)
       
   579 		aName.Append(Drive());
       
   580 	if (aFlags & EIncludePath)
       
   581 		{
       
   582 		if (PathLen() && iName[iPathPos]!='\\')
       
   583 			aName.Append('\\');
       
   584 		aName.Append(Path());
       
   585 		}
       
   586 	if (aFlags & EIncludeBase)
       
   587 		aName.Append(Base());
       
   588 	if ((aFlags & EForceVer) || ((aFlags & EIncludeVer) && VerLen()) )
       
   589 		{
       
   590 		aName.Append('{');
       
   591 		aName.AppendNumFixedWidth(iVersion, EHex, 8);
       
   592 		aName.Append('}');		
       
   593 		}
       
   594 	if ((aFlags & EForceUid) || ((aFlags & EIncludeUid) && UidLen()) )
       
   595 		{
       
   596 		aName.Append('[');
       
   597 		aName.AppendNumFixedWidth(iUid, EHex, 8);
       
   598 		aName.Append(']');
       
   599 		}
       
   600 	if (aFlags & EIncludeExt)
       
   601 		aName.Append(Ext());
       
   602 	}
       
   603 
       
   604 
       
   605 void CDllChecker::GetFileNameAndUid(CDllInfo &aDllInfo, const TDesC8 &aExportName)
       
   606 //	
       
   607 //	Gets filename and UID 
       
   608 //
       
   609 	{	
       
   610 	TFileNameInfo filename;
       
   611 	filename.Set(aExportName,TFileNameInfo::EAllowUid|TFileNameInfo::EAllowDecimalVersion);
       
   612 	TBuf8<KMaxFileName> narrowDllName;
       
   613 	filename.GetName(narrowDllName,TFileNameInfo::EIncludeBaseExt);
       
   614 	aDllInfo.iDllName.Copy(narrowDllName);
       
   615 	aDllInfo.iUid=TUid::Uid(filename.Uid());
       
   616 	TUint32 version = filename.Version();
       
   617 	aDllInfo.iMajorVersion = version >> 16;
       
   618 	aDllInfo.iMinorVersion = version & 0xFFFF;
       
   619 	}
       
   620 
       
   621 
       
   622 TInt CDllChecker::CheckUid3(TInt32 aUid3,TUid aUid)
       
   623 //
       
   624 //	Check that Uid3 is the same in the iDllName and as noted by the Image Header
       
   625 //	aUid3 is the value found by the image header
       
   626 //	aUid is the value found by parsing the result of block->dllname 
       
   627 //	using GetFileNameAndUid()
       
   628 	{
       
   629 
       
   630 	if ((aUid.iUid)==aUid3)
       
   631 		{
       
   632 
       
   633 		__PRINT(_L("\tUid3 is valid\r\n"));
       
   634 		return KErrNone;
       
   635 		}
       
   636 	else
       
   637 		{
       
   638 
       
   639 		__PRINT(_L("\tUid3 value is not supported\r\n"));
       
   640 		return (EUidNotSupported);
       
   641 		}
       
   642 	}
       
   643 
       
   644 
       
   645 
       
   646 TInt CDllChecker::FindDll(TDes& aDllName,TFileName& aFileName, const TDesC& aPath)
       
   647 //
       
   648 // Search for a dll in the following sequence ...
       
   649 // 1. Supplied path parameter
       
   650 // 2. System directories on all drives
       
   651 //
       
   652 	{
       
   653 	TFindFile findFile(Fs());
       
   654 	TInt r=findFile.FindByPath(aDllName,&aPath);
       
   655 	if (r==KErrNone)
       
   656 		{
       
   657 		aFileName=findFile.File();	
       
   658 
       
   659 		__PRINT1(_L("\t\"%S\" was found (supplied path)\r\n"),&aFileName);
       
   660 
       
   661 		return(r);
       
   662 		}
       
   663 
       
   664 	r=findFile.FindByDir(aDllName,_L("Y:\\Sys\\Bin\\"));
       
   665 	if (r==KErrNone)
       
   666 		{
       
   667 		aFileName=findFile.File();	
       
   668 
       
   669 		__PRINT1(_L("\t\"%S\" was found (system directory)\r\n"),&aFileName);
       
   670 
       
   671 		return(r);
       
   672 		}
       
   673 	/*
       
   674 	if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
       
   675 		{
       
   676 		r=findFile.FindByDir(aDllName,_L("\\System\\Bin\\"));
       
   677 		if (r==KErrNone)
       
   678 			{
       
   679 			aFileName=findFile.File();	
       
   680 
       
   681 			__PRINT1(_L("\t\"%S\" was found (system directory)\r\n"),&aFileName);
       
   682 
       
   683 			return(r);
       
   684 			}
       
   685 		}
       
   686 	*/
       
   687 	__PRINT1(_L("\t\"%S\" was not found\r\n"),&aDllName);
       
   688 
       
   689 	return(KErrNotFound);
       
   690 	}
       
   691 
       
   692 void CDllChecker::ListArray()
       
   693 	{
       
   694 	const TInt elements=iDllArray.Count();
       
   695 	
       
   696 	Printf(_L("Number of dependencies checked = %d\r\n"),elements);
       
   697 
       
   698 	for (TInt i=0;i<elements; i++)
       
   699 		{
       
   700 		CDllInfo& info = *(iDllArray[i]);
       
   701 		TResultCheck res = info.iResult;
       
   702 		TBool print = iVerbose || (res != EFileFoundAndUidSupported && res != ENoImportData && res != EAlreadyOpen);
       
   703 		if (print) Printf(_L("% 2d: %-15S  Uid3: [%08x] "),(i+1),&info.iDllName,(info.iUid));
       
   704 		if (!print) continue;
       
   705 		switch(res)
       
   706 			{
       
   707 		case(ENoImportData):
       
   708 			Printf(_L("--- No import data\r\n"));
       
   709 			break;
       
   710 
       
   711 		case(EUidNotSupported):
       
   712 			Printf(_L("--- Uid3 is not supported\r\n"));
       
   713 			break;
       
   714 
       
   715 		case(ENotFound):
       
   716 			Printf(_L("--- File was not found\r\n"));
       
   717 			break;
       
   718 
       
   719 		case(ECouldNotOpenFile):
       
   720 			Printf(_L("--- File could not be opened\r\n"));
       
   721 			break;
       
   722 
       
   723 		case(EUidDifference):
       
   724 			Printf(_L("--- File already noted with different Uid\r\n"));
       
   725 			break;
       
   726 
       
   727 		case(EAlreadyOpen):
       
   728 			Printf(_L("--- File already open\r\n"));
       
   729 			break;
       
   730 		
       
   731 		case(EFileFoundAndUidSupported):
       
   732 			Printf(_L("--- File was found, Uid3 is supported\r\n"));
       
   733 			break;
       
   734 
       
   735 		case ERequiredCapabilitiesMissing:
       
   736 			{
       
   737 			Printf(_L("--- Dll is missing capabilities:"));
       
   738 			for (TInt i = 0; i < ECapability_Limit; i++)
       
   739 				{
       
   740 				TCapability c = (TCapability)i;
       
   741 				if (iRequiredCaps->HasCapability(c) && !info.iDllCaps.HasCapability(c))
       
   742 					{
       
   743 					Printf(_L8(" %s"), CapabilityNames[i]);
       
   744 					}
       
   745 				}
       
   746 			Printf(_L("\r\n"));
       
   747 			break;
       
   748 			}
       
   749 		case EOrdinalMissing:
       
   750 			Printf(_L("--- Required ordinal(s) missing\r\n"));
       
   751 			break;
       
   752 		case EVersionMismatch:
       
   753 			Printf(_L("--- Version mismatch\r\n"));
       
   754 			break;
       
   755 		default:	//	Will never reach here
       
   756 			Printf(_L("--- Undefined\r\n"));
       
   757 			break;
       
   758 			}
       
   759 		}
       
   760 	}