os/kernelhwsrv/userlibandfileserver/fileserver/etshell/ts_deps.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// f32\etshell\ts_deps.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "ts_std.h"
sl@0
    19
#include "f32image.h"
sl@0
    20
#include <e32uid.h>
sl@0
    21
#include "sf_deflate.h"
sl@0
    22
#include "sf_image.h"
sl@0
    23
sl@0
    24
//#define _DETAILED_CHECK	//	Select for detailed dependency check
sl@0
    25
sl@0
    26
#if defined(_DETAILED_CHECK)	//	Prints information to screen
sl@0
    27
#define __PRINT(t) {CShell::TheConsole->Printf(t);}
sl@0
    28
#define __PRINT1(t,a) {CShell::TheConsole->Printf(t,a);}
sl@0
    29
#define __PRINT2(t,a,b) {CShell::TheConsole->Printf(t,a,b);}
sl@0
    30
#define __PRINTWAIT(t){CShell::TheConsole->Printf(t);CShell::TheConsole->Getch();}
sl@0
    31
#else
sl@0
    32
#define __PRINT(t)
sl@0
    33
#define __PRINT1(t,a)
sl@0
    34
#define __PRINT2(t,a,b)
sl@0
    35
#define __PRINTWAIT(t)
sl@0
    36
#endif
sl@0
    37
sl@0
    38
/*
sl@0
    39
  
sl@0
    40
CDllChecker::GetImportDataL(aFilename) reads the Image Header, Import Section 
sl@0
    41
and all import data for aFilename.  If aFilename is a ROM dll, and thus has no 
sl@0
    42
import data, or if the file contains no import data for some other reason the 
sl@0
    43
function leaves with KErrGeneral. If a file is compressed, function calls 
sl@0
    44
appropriate decompression routine to inflate the import data.
sl@0
    45
The function then calls GetDllTableL function which 
sl@0
    46
reads the first import block and enters a "for" loop. The Dll's name and Uid3 are obtained 
sl@0
    47
from CDllChecker::GetFileNameAndUid().  If the Dll name does not occur in the 
sl@0
    48
array of previously checked Dlls, CDllChecker::FindDll() is called.  If the Dll 
sl@0
    49
is found,the function then calls CDllChecker::GetImportDataL on the filename acquired by 
sl@0
    50
GetFileNameAndUid()(recursive call). 
sl@0
    51
sl@0
    52
If the Dll contains no import data or cannot be found, or if the Uid is invalid,
sl@0
    53
the next import is checked.
sl@0
    54
sl@0
    55
The Uid3 value is checked by calling CDllChecker::CheckUid.  This compares the 
sl@0
    56
Uid3 value found in the image header of the file, with that found by 
sl@0
    57
GetFileNameAndUid().  If there are any discrepancies,these are noted.
sl@0
    58
sl@0
    59
Each potential import is added to the array by dllAppendL(TResultCheck) to 
sl@0
    60
indicate its import status.
sl@0
    61
sl@0
    62
CDllChecker::ListArray() lists the contents of the array when all imports
sl@0
    63
have been checked.
sl@0
    64
*/
sl@0
    65
sl@0
    66
sl@0
    67
CDllChecker::CDllChecker()
sl@0
    68
//
sl@0
    69
//	Constructor
sl@0
    70
//
sl@0
    71
	{
sl@0
    72
	iDllArray=NULL;
sl@0
    73
	iCalls=0;
sl@0
    74
	}
sl@0
    75
sl@0
    76
sl@0
    77
sl@0
    78
void CDllChecker::ConstructL()
sl@0
    79
//
sl@0
    80
//	Creates an array to hold DLLs referenced by this executable	
sl@0
    81
//
sl@0
    82
	{
sl@0
    83
	iDllArray = new(ELeave)CArrayFixFlat<SDllInfo>(4);			
sl@0
    84
	__PRINT(_L(" Successfully created iDllArray\n"));	
sl@0
    85
	}
sl@0
    86
sl@0
    87
sl@0
    88
CDllChecker::~CDllChecker()
sl@0
    89
//
sl@0
    90
//	Destructor
sl@0
    91
//
sl@0
    92
	{
sl@0
    93
    delete iDllArray;
sl@0
    94
	}
sl@0
    95
sl@0
    96
sl@0
    97
GLDEF_C void Get16BitDllName(TDes8& aDllName,TDes& aFileName)
sl@0
    98
//
sl@0
    99
//	Convert an 8 bit name to a 16 bit name - zero padded automatically
sl@0
   100
//	No effect in 8 bit builds - just sets aFileName to aDllName
sl@0
   101
//
sl@0
   102
	{
sl@0
   103
	aFileName.SetLength(aDllName.Length());
sl@0
   104
	aFileName.Copy(aDllName);
sl@0
   105
	}
sl@0
   106
sl@0
   107
void FileCleanup(TAny* aPtr)
sl@0
   108
	{
sl@0
   109
	TFileInput* f=(TFileInput*)aPtr;
sl@0
   110
	f->Cancel();
sl@0
   111
	delete f;
sl@0
   112
	}
sl@0
   113
sl@0
   114
void CDllChecker::LoadFileInflateL(E32ImageHeaderComp* aHeader,TUint8* aRestOfFileData,TUint32 aRestOfFileSize)
sl@0
   115
	{
sl@0
   116
	TInt pos = aHeader->TotalSize();
sl@0
   117
	User::LeaveIfError(iFile.Seek(ESeekStart,pos)); // Start at beginning of compressed data
sl@0
   118
sl@0
   119
	TFileInput* file = new (ELeave) TFileInput(iFile);
sl@0
   120
	CleanupStack::PushL(TCleanupItem(&FileCleanup,file));
sl@0
   121
	CInflater* inflater=CInflater::NewLC(*file);
sl@0
   122
	
sl@0
   123
	if (aHeader->iCodeSize)
sl@0
   124
		{
sl@0
   125
		TUint8* CodeData = (TUint8*)User::AllocLC(aHeader->iCodeSize );
sl@0
   126
		TInt count=inflater->ReadL((TUint8*)CodeData ,aHeader->iCodeSize,&Mem::Move);
sl@0
   127
		if(count!=aHeader->iCodeSize)
sl@0
   128
			User::Leave(KErrCorrupt);
sl@0
   129
		CleanupStack::PopAndDestroy(CodeData);
sl@0
   130
		}
sl@0
   131
	
sl@0
   132
	if (aRestOfFileSize)
sl@0
   133
		{
sl@0
   134
		TUint32 count=inflater->ReadL(aRestOfFileData,aRestOfFileSize,&Mem::Move);
sl@0
   135
		if(count!=aRestOfFileSize)
sl@0
   136
			User::Leave(KErrCorrupt);
sl@0
   137
		}
sl@0
   138
	CleanupStack::PopAndDestroy(2,file);
sl@0
   139
	}
sl@0
   140
sl@0
   141
void CDllChecker::LoadFileNoCompressL(E32ImageHeaderComp* aHeader,TUint8* aRestOfFileData,TUint32 aRestOfFileSize)
sl@0
   142
	{
sl@0
   143
	TInt pos = (aHeader->TotalSize()+aHeader->iCodeSize);
sl@0
   144
	if (aRestOfFileSize)
sl@0
   145
		{
sl@0
   146
		User::LeaveIfError(iFile.Seek(ESeekStart,pos)); // Start at beginning of import table
sl@0
   147
		TPtr8 ptrToData((TText8*)(aRestOfFileData),aRestOfFileSize,aRestOfFileSize);
sl@0
   148
		User::LeaveIfError(iFile.Read(ptrToData, (TInt)aRestOfFileSize));	
sl@0
   149
		}
sl@0
   150
	}	
sl@0
   151
//function loads file's import information calling decompression routine if needed
sl@0
   152
TInt CDllChecker::LoadFile(TUint32 aCompression,E32ImageHeaderComp* aHeader,TUint8* aRestOfFileData,TUint32 aRestOfFileSize)
sl@0
   153
	{
sl@0
   154
	TInt r=KErrNone;
sl@0
   155
	if(aCompression==KFormatNotCompressed)
sl@0
   156
		{
sl@0
   157
		TRAP(r,LoadFileNoCompressL(aHeader,aRestOfFileData,aRestOfFileSize));		
sl@0
   158
		}
sl@0
   159
	else if(aCompression==KUidCompressionDeflate)
sl@0
   160
		{
sl@0
   161
		TRAP(r,LoadFileInflateL(aHeader,aRestOfFileData,aRestOfFileSize));
sl@0
   162
		}
sl@0
   163
	else
sl@0
   164
		r=KErrNotSupported;
sl@0
   165
sl@0
   166
	return r;
sl@0
   167
	}
sl@0
   168
								
sl@0
   169
//function iterates through the list of libraries the current executable depends on
sl@0
   170
//for each dependency in the list the function checks whether the .dll being checked is already added to the array of dependencies
sl@0
   171
//if not, the function adds dependency being checked to the array of dependencies and calls GetImportDataL function recursively
sl@0
   172
void CDllChecker::GetDllTableL(TUint8* aImportData, TInt aDllRefTableCount,TUint aFlags)
sl@0
   173
	{
sl@0
   174
	E32ImportBlock* block = (E32ImportBlock*)((TUint8*)aImportData+sizeof(E32ImportSection));
sl@0
   175
sl@0
   176
	//*********Beginning of the loop*********
sl@0
   177
	for (TInt i=0; i<aDllRefTableCount; i++)	
sl@0
   178
		{
sl@0
   179
sl@0
   180
		SDllInfo dllInfo;		
sl@0
   181
		TText8* dllName=(aImportData+block->iOffsetOfDllName);
sl@0
   182
		TPtrC8 dllNamePtr(dllName, User::StringLength(dllName));
sl@0
   183
		GetFileNameAndUid(dllInfo,dllNamePtr);//Gets name and Uid of dependency
sl@0
   184
		TUid* pointer=&dllInfo.iUid;		
sl@0
   185
		__PRINT(_L(" Check Dll has not already been imported\n"));		
sl@0
   186
		TKeyArrayFix key(0,ECmpFolded);	
sl@0
   187
		TInt pos;		
sl@0
   188
		TInt r=iDllArray->Find(dllInfo,key,pos);//	Search array by Dll Name		
sl@0
   189
		if (r==KErrNone)	//	**********IT IS ALREADY IN THE ARRAY***********
sl@0
   190
			{
sl@0
   191
			__PRINT1(_L(" Dll %S has already been checked\n"),&dllInfo.iDllName);
sl@0
   192
sl@0
   193
			//Check its Uid3 against that noted in the array		
sl@0
   194
			if (iDllArray->At(pos).iUid!=dllInfo.iUid)	
sl@0
   195
				{
sl@0
   196
			//	Uid3 is different to that of the same named Dll
sl@0
   197
			//	Add it to the array for comparative purposes			
sl@0
   198
				__PRINT2(_L(" Uid3 [%08x] for %S is different from that noted previously\n"),dllInfo.iUid, &dllInfo.iDllName);
sl@0
   199
				dllInfo.iResult=EUidDifference;
sl@0
   200
			
sl@0
   201
			//	Add this entry to iDllArray
sl@0
   202
				DllAppendL(dllInfo);							
sl@0
   203
				}
sl@0
   204
			}//	Run to the end of the "for" loop for this i value
sl@0
   205
		else	//	**********THE FILE IS NOT YET IN THE ARRAY**********				
sl@0
   206
			{
sl@0
   207
			__PRINT(_L(" Dll has not previously been checked\n"));
sl@0
   208
sl@0
   209
		//	Check through it and add the relevant information to the array
sl@0
   210
		
sl@0
   211
		//	Search for the DLL
sl@0
   212
			TPath aPath=(TPath)CShell::currentPath;
sl@0
   213
			TFileName fileName;
sl@0
   214
			TName dll16BitName;
sl@0
   215
sl@0
   216
#if defined(UNICODE)
sl@0
   217
			Get16BitDllName(dllInfo.iDllName,dll16BitName);
sl@0
   218
#else
sl@0
   219
			dll16BitName=(dllInfo.iDllName);
sl@0
   220
#endif
sl@0
   221
			r=FindDll(dll16BitName,fileName,aPath);
sl@0
   222
			
sl@0
   223
			__PRINT1(_L("dll16BitName=%S\n"),&dll16BitName);
sl@0
   224
			__PRINTWAIT(_L(" Press any key to continue\n"));
sl@0
   225
sl@0
   226
			if (r==KErrNotFound)	//	Could not find Dll
sl@0
   227
				{
sl@0
   228
				dllInfo.iResult=ENotFound;
sl@0
   229
				}//	Run to the end of the "for" loop for this i value
sl@0
   230
sl@0
   231
			else	//	File was located 
sl@0
   232
					
sl@0
   233
//	Go recursive.  Call GetImportDataL on the new dll, if it imports anything.
sl@0
   234
//	ROM dlls have no import data so this is never called for ROM dlls.
sl@0
   235
//	This *will* terminate.  It is only called on "new" dlls not in the array.
sl@0
   236
		
sl@0
   237
				{				
sl@0
   238
				__PRINT(_L(" ****Go recursive****\n"));
sl@0
   239
				__PRINTWAIT(_L(" Press any key to continue\n"));
sl@0
   240
								
sl@0
   241
				iCalls++;
sl@0
   242
				
sl@0
   243
				TRAP(r,GetImportDataL(fileName, pointer));				
sl@0
   244
			//	Pass in (parsed) fileName and Uid3 (from file header)
sl@0
   245
				switch(r)		
sl@0
   246
					{
sl@0
   247
				case(KErrGeneral):	//	No import data
sl@0
   248
						{
sl@0
   249
						dllInfo.iResult=ENoImportData;
sl@0
   250
						break;
sl@0
   251
					//	Run to the end of the for loop for this i value
sl@0
   252
						}
sl@0
   253
				case(EUidNotSupported):
sl@0
   254
						{
sl@0
   255
						dllInfo.iResult=EUidNotSupported;
sl@0
   256
						break;
sl@0
   257
						}
sl@0
   258
				case(KErrNone):	//	Import data was read
sl@0
   259
						{
sl@0
   260
						dllInfo.iResult=EFileFoundAndUidSupported;
sl@0
   261
						break;
sl@0
   262
					//	Run to the end of the for loop for this i value
sl@0
   263
						}
sl@0
   264
				case(KErrInUse):
sl@0
   265
						{
sl@0
   266
						__PRINT2(_L(" File %S is already open\n"),&fileName,r);
sl@0
   267
						dllInfo.iResult=EAlreadyOpen;
sl@0
   268
						break;
sl@0
   269
						}
sl@0
   270
				case(KErrCorrupt):
sl@0
   271
						{
sl@0
   272
						__PRINT2(_L(" File %S has unexpected format\n"),&fileName,r);
sl@0
   273
						dllInfo.iResult=EAlreadyOpen;
sl@0
   274
						break;
sl@0
   275
						}
sl@0
   276
				default:
sl@0
   277
						{
sl@0
   278
						__PRINT1(_L(" File %S could not be opened \n"),&fileName);
sl@0
   279
						dllInfo.iResult=ECouldNotOpenFile;
sl@0
   280
						break;
sl@0
   281
						}
sl@0
   282
					//	Run to the end of the for loop for this i value							
sl@0
   283
					}	
sl@0
   284
				}
sl@0
   285
		
sl@0
   286
		//	Add the information about the dependency to iDllArray
sl@0
   287
			DllAppendL(dllInfo);			
sl@0
   288
			}
sl@0
   289
//	Runs to here when all import data has been read for this i value
sl@0
   290
sl@0
   291
		__PRINT(_L(" Go to next dll to be imported...\n"));
sl@0
   292
		__PRINTWAIT(_L(" Press any key to continue\n"));
sl@0
   293
			
sl@0
   294
		block = (E32ImportBlock*)block->NextBlock(E32ImageHeader::ImpFmtFromFlags(aFlags));
sl@0
   295
		
sl@0
   296
		}//	The end of the loop.  Every DLL has been located	
sl@0
   297
sl@0
   298
	}
sl@0
   299
sl@0
   300
sl@0
   301
void CDllChecker::GetImportDataL(const TDesC& aFileName, TUid* aPointer)
sl@0
   302
	{
sl@0
   303
	TInt cleanupCount=0;
sl@0
   304
	//	Check that the file is not a ROM dll.  These have no import data	
sl@0
   305
	if (ShellFunction::TheShell->TheFs.IsFileInRom(aFileName))
sl@0
   306
		{		
sl@0
   307
		User::Leave(KErrGeneral);
sl@0
   308
		}
sl@0
   309
	
sl@0
   310
	//open file for reading and push it to autoclose stack
sl@0
   311
	TAutoClose<RFile> autoFile;
sl@0
   312
	User::LeaveIfError(autoFile.iObj.Open(CShell::TheFs,aFileName,EFileStream));
sl@0
   313
	autoFile.PushL();
sl@0
   314
	cleanupCount++;
sl@0
   315
	iFile=autoFile.iObj;
sl@0
   316
		
sl@0
   317
	//Create a pointer to an Image Header
sl@0
   318
	//reserve enough memory for compressed file header because we don't know whether the file is compressed or not 
sl@0
   319
	E32ImageHeaderComp* imageHeader=new(ELeave)E32ImageHeaderComp;
sl@0
   320
	CleanupStack::PushL(imageHeader);
sl@0
   321
	cleanupCount++;
sl@0
   322
	
sl@0
   323
	//read file header
sl@0
   324
	TPtr8 ptrToImageHeader((TText8*)(imageHeader),sizeof(E32ImageHeaderComp),sizeof(E32ImageHeaderComp));
sl@0
   325
	User::LeaveIfError(iFile.Read(ptrToImageHeader,sizeof(E32ImageHeaderComp)));
sl@0
   326
	
sl@0
   327
	if (imageHeader->iImportOffset==0)//	File contains no import data
sl@0
   328
		{	
sl@0
   329
		User::Leave(KErrGeneral);
sl@0
   330
		}	
sl@0
   331
sl@0
   332
	TUint32 compression = imageHeader->CompressionType();
sl@0
   333
	TInt restOfFileSize=0;
sl@0
   334
	TUint8* restOfFileData=NULL;
sl@0
   335
	//detect the size of import information
sl@0
   336
	if (compression != KFormatNotCompressed)
sl@0
   337
		{
sl@0
   338
		// Compressed executable
sl@0
   339
		// iCodeOffset	= header size for format V or above
sl@0
   340
		//				= sizeof(E32ImageHeader) for format J
sl@0
   341
		restOfFileSize = imageHeader->UncompressedFileSize() - imageHeader->iCodeOffset;
sl@0
   342
		}
sl@0
   343
	else
sl@0
   344
		{
sl@0
   345
		TInt FileSize;
sl@0
   346
		iFile.Size(FileSize); 		
sl@0
   347
		restOfFileSize = FileSize-imageHeader->TotalSize();
sl@0
   348
		}	
sl@0
   349
	restOfFileSize -= imageHeader->iCodeSize; // the size of the exe less header & code
sl@0
   350
	
sl@0
   351
	//allocate memory for import information
sl@0
   352
	if (restOfFileSize >0)
sl@0
   353
		{
sl@0
   354
		restOfFileData = (TUint8*)User::AllocLC(restOfFileSize );		
sl@0
   355
		cleanupCount++;
sl@0
   356
		}
sl@0
   357
sl@0
   358
	User::LeaveIfError(LoadFile(compression,imageHeader,restOfFileData,restOfFileSize)); // Read import information in
sl@0
   359
			
sl@0
   360
	TInt32 uid3=imageHeader->iUid3;
sl@0
   361
	if(iCalls!=0)	//	Only check Uid3 of dependencies (ie only after first 
sl@0
   362
		{			//	call of recursive function)
sl@0
   363
		TInt r=CheckUid3(uid3,*aPointer);
sl@0
   364
sl@0
   365
		if (r!=KErrNone) //	Dll's Uid3 is not valid
sl@0
   366
			User::Leave(EUidNotSupported);						
sl@0
   367
		}
sl@0
   368
				
sl@0
   369
	TInt bufferOffset=imageHeader->iImportOffset-(imageHeader->iCodeOffset + imageHeader->iCodeSize);
sl@0
   370
	if( TInt(bufferOffset+sizeof(E32ImportSection))>restOfFileSize)
sl@0
   371
		User::Leave(KErrCorrupt);		
sl@0
   372
	//get the table of dependencies
sl@0
   373
	GetDllTableL(restOfFileData+bufferOffset,imageHeader->iDllRefTableCount,imageHeader->iFlags);
sl@0
   374
sl@0
   375
	CleanupStack::PopAndDestroy(cleanupCount);	
sl@0
   376
	}
sl@0
   377
sl@0
   378
sl@0
   379
TUint8* CDllChecker::NextBlock(TUint8* aBlock)
sl@0
   380
	{
sl@0
   381
	E32ImportBlock* block;	
sl@0
   382
	//	Advance the pointer to the next block	
sl@0
   383
	block=(E32ImportBlock*)aBlock;
sl@0
   384
	aBlock=(aBlock+sizeof(E32ImportBlock)+((block->iNumberOfImports)*sizeof(TUint)));		
sl@0
   385
	return (aBlock);
sl@0
   386
	}
sl@0
   387
sl@0
   388
sl@0
   389
TFileNameInfo::TFileNameInfo()
sl@0
   390
	{
sl@0
   391
	memclr(this, sizeof(TFileNameInfo));
sl@0
   392
	}
sl@0
   393
sl@0
   394
TInt TFileNameInfo::Set(const TDesC8& aFileName, TUint aFlags)
sl@0
   395
	{
sl@0
   396
	iUid = 0;
sl@0
   397
	iVersion = 0;
sl@0
   398
	iPathPos = 0;
sl@0
   399
	iName = aFileName.Ptr();
sl@0
   400
	iLen = aFileName.Length();
sl@0
   401
	iExtPos = aFileName.LocateReverse('.');
sl@0
   402
	if (iExtPos<0)
sl@0
   403
		iExtPos = iLen;
sl@0
   404
	TInt osq = aFileName.LocateReverse('[');
sl@0
   405
	TInt csq = aFileName.LocateReverse(']');
sl@0
   406
	if (!(aFlags & EAllowUid) && (osq>=0 || csq>=0))
sl@0
   407
		{
sl@0
   408
		return KErrBadName;
sl@0
   409
		}
sl@0
   410
	if (osq>=iExtPos || csq>=iExtPos)
sl@0
   411
		{
sl@0
   412
		return KErrBadName;
sl@0
   413
		}
sl@0
   414
	TInt p = iExtPos;
sl@0
   415
	if ((aFlags & EAllowUid) && p>=10 && iName[p-1]==']' && iName[p-10]=='[')
sl@0
   416
		{
sl@0
   417
		TPtrC8 uidstr(iName + p - 9, 8);
sl@0
   418
		TLex8 uidlex(uidstr);
sl@0
   419
		TUint32 uid = 0;
sl@0
   420
		TInt r = uidlex.Val(uid, EHex);
sl@0
   421
		if (r==KErrNone && uidlex.Eos())
sl@0
   422
			iUid = uid, p -= 10;
sl@0
   423
		}
sl@0
   424
	iUidPos = p;
sl@0
   425
	TInt ob = aFileName.LocateReverse('{');
sl@0
   426
	TInt cb = aFileName.LocateReverse('}');
sl@0
   427
	if (ob>=iUidPos || cb>=iUidPos)
sl@0
   428
		{
sl@0
   429
		return KErrBadName;
sl@0
   430
		}
sl@0
   431
	if (ob>=0 && cb>=0 && p-1==cb)
sl@0
   432
		{
sl@0
   433
		TPtrC8 p8(iName, p);
sl@0
   434
		TInt d = p8.LocateReverse('.');
sl@0
   435
		TPtrC8 verstr(iName+ob+1, p-ob-2);
sl@0
   436
		TLex8 verlex(verstr);
sl@0
   437
		if (ob==p-10 && d<ob)
sl@0
   438
			{
sl@0
   439
			TUint32 ver = 0;
sl@0
   440
			TInt r = verlex.Val(ver, EHex);
sl@0
   441
			if (r==KErrNone && verlex.Eos())
sl@0
   442
				iVersion = ver, p = ob;
sl@0
   443
			}
sl@0
   444
		else if (d>ob && p-1>d && (aFlags & EAllowDecimalVersion))
sl@0
   445
			{
sl@0
   446
			TUint32 maj = 0;
sl@0
   447
			TUint32 min = 0;
sl@0
   448
			TInt r = verlex.Val(maj, EDecimal);
sl@0
   449
			TUint c = (TUint)verlex.Get();
sl@0
   450
			TInt r2 = verlex.Val(min, EDecimal);
sl@0
   451
			if (r==KErrNone && c=='.' && r2==KErrNone && verlex.Eos() && maj<32768 && min<32768)
sl@0
   452
				iVersion = (maj << 16) | min, p = ob;
sl@0
   453
			}
sl@0
   454
		}
sl@0
   455
	iVerPos = p;
sl@0
   456
	if (iLen>=2 && iName[1]==':')
sl@0
   457
		{
sl@0
   458
		TUint c = iName[0];
sl@0
   459
		if (c!='?' || !(aFlags & EAllowPlaceholder))
sl@0
   460
			{
sl@0
   461
			c |= 0x20;
sl@0
   462
			if (c<'a' || c>'z')
sl@0
   463
				{
sl@0
   464
				return KErrBadName;
sl@0
   465
				}
sl@0
   466
			}
sl@0
   467
		iPathPos = 2;
sl@0
   468
		}
sl@0
   469
	TPtrC8 pathp(iName+iPathPos, iVerPos-iPathPos);
sl@0
   470
	if (pathp.Locate('[')>=0 || pathp.Locate(']')>=0 || pathp.Locate('{')>=0 || pathp.Locate('}')>=0 || pathp.Locate(':')>=0)
sl@0
   471
		{
sl@0
   472
		return KErrBadName;
sl@0
   473
		}
sl@0
   474
	iBasePos = pathp.LocateReverse('\\') + 1 + iPathPos;
sl@0
   475
	return KErrNone;
sl@0
   476
	}
sl@0
   477
sl@0
   478
void TFileNameInfo::GetName(TDes8& aName, TUint aFlags) const
sl@0
   479
	{
sl@0
   480
	if (aFlags & EIncludeDrive)
sl@0
   481
		aName.Append(Drive());
sl@0
   482
	if (aFlags & EIncludePath)
sl@0
   483
		{
sl@0
   484
		if (PathLen() && iName[iPathPos]!='\\')
sl@0
   485
			aName.Append('\\');
sl@0
   486
		aName.Append(Path());
sl@0
   487
		}
sl@0
   488
	if (aFlags & EIncludeBase)
sl@0
   489
		aName.Append(Base());
sl@0
   490
	if ((aFlags & EForceVer) || ((aFlags & EIncludeVer) && VerLen()) )
sl@0
   491
		{
sl@0
   492
		aName.Append('{');
sl@0
   493
		aName.AppendNumFixedWidth(iVersion, EHex, 8);
sl@0
   494
		aName.Append('}');		
sl@0
   495
		}
sl@0
   496
	if ((aFlags & EForceUid) || ((aFlags & EIncludeUid) && UidLen()) )
sl@0
   497
		{
sl@0
   498
		aName.Append('[');
sl@0
   499
		aName.AppendNumFixedWidth(iUid, EHex, 8);
sl@0
   500
		aName.Append(']');
sl@0
   501
		}
sl@0
   502
	if (aFlags & EIncludeExt)
sl@0
   503
		aName.Append(Ext());
sl@0
   504
	}
sl@0
   505
sl@0
   506
sl@0
   507
void CDllChecker::GetFileNameAndUid(SDllInfo &aDllInfo, const TDesC8 &aExportName)
sl@0
   508
//	
sl@0
   509
//	Gets filename and UID 
sl@0
   510
//
sl@0
   511
	{	
sl@0
   512
	TFileNameInfo filename;
sl@0
   513
	filename.Set(aExportName,TFileNameInfo::EAllowUid|TFileNameInfo::EAllowDecimalVersion);
sl@0
   514
	filename.GetName(aDllInfo.iDllName,TFileNameInfo::EIncludeBaseExt);
sl@0
   515
	aDllInfo.iUid=TUid::Uid(filename.Uid());
sl@0
   516
	}
sl@0
   517
sl@0
   518
sl@0
   519
TInt CDllChecker::CheckUid3(TInt32 aUid3,TUid aUid)
sl@0
   520
//
sl@0
   521
//	Check that Uid3 is the same in the iDllName and as noted by the Image Header
sl@0
   522
//	aUid3 is the value found by the image header
sl@0
   523
//	aUid is the value found by parsing the result of block->dllname 
sl@0
   524
//	using GetFileNameAndUid()
sl@0
   525
	{
sl@0
   526
sl@0
   527
	if ((aUid.iUid)==aUid3)
sl@0
   528
		{
sl@0
   529
sl@0
   530
		__PRINT(_L(" Uid3 is valid\n"));
sl@0
   531
sl@0
   532
		return KErrNone;
sl@0
   533
		}
sl@0
   534
	else
sl@0
   535
		{
sl@0
   536
sl@0
   537
		__PRINT(_L(" Uid3 value is not supported\n"));
sl@0
   538
sl@0
   539
		return (EUidNotSupported);
sl@0
   540
		}
sl@0
   541
	}
sl@0
   542
sl@0
   543
sl@0
   544
sl@0
   545
TInt CDllChecker::FindDll(TDes& aDllName,TFileName& aFileName, TPath& aPath)
sl@0
   546
//
sl@0
   547
// Search for a dll in the following sequence ...
sl@0
   548
// 1. Supplied path parameter
sl@0
   549
// 2. System directories on all drives
sl@0
   550
//
sl@0
   551
	{
sl@0
   552
	TFindFile findFile(CShell::TheFs);
sl@0
   553
	TInt r=findFile.FindByPath(aDllName,&aPath);
sl@0
   554
	if (r==KErrNone)
sl@0
   555
		{
sl@0
   556
		aFileName=findFile.File();	
sl@0
   557
sl@0
   558
		__PRINT1(_L(" Dependency %S was found (supplied path)\n"),&aFileName);
sl@0
   559
sl@0
   560
		return(r);
sl@0
   561
		}
sl@0
   562
sl@0
   563
	r=findFile.FindByDir(aDllName,_L("\\Sys\\Bin\\"));
sl@0
   564
	if (r==KErrNone)
sl@0
   565
		{
sl@0
   566
		aFileName=findFile.File();	
sl@0
   567
sl@0
   568
		__PRINT1(_L(" Dependency %S was found (system directory)\n"),&aFileName);
sl@0
   569
sl@0
   570
		return(r);
sl@0
   571
		}
sl@0
   572
sl@0
   573
	if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
sl@0
   574
		{
sl@0
   575
		r=findFile.FindByDir(aDllName,_L("\\System\\Bin\\"));
sl@0
   576
		if (r==KErrNone)
sl@0
   577
			{
sl@0
   578
			aFileName=findFile.File();	
sl@0
   579
sl@0
   580
			__PRINT1(_L(" Dependency %S was found (system directory)\n"),&aFileName);
sl@0
   581
sl@0
   582
			return(r);
sl@0
   583
			}
sl@0
   584
		}
sl@0
   585
sl@0
   586
	__PRINT1(_L(" Dependency %S was not found\n"),&aDllName);
sl@0
   587
sl@0
   588
	return(KErrNotFound);
sl@0
   589
	}
sl@0
   590
sl@0
   591
sl@0
   592
sl@0
   593
sl@0
   594
void CDllChecker::DllAppendL(const SDllInfo& aDllInfo)
sl@0
   595
	{
sl@0
   596
	TInt leaveCode=KErrNone;				
sl@0
   597
	TRAP(leaveCode,iDllArray->AppendL(aDllInfo));	//	Add it to iDllArray
sl@0
   598
	
sl@0
   599
	if (leaveCode!=KErrNone)
sl@0
   600
		{
sl@0
   601
		__PRINT(_L(" Could not add Dll to the array\n"));
sl@0
   602
		__PRINTWAIT(_L(" Press any key to continue\n"));
sl@0
   603
		
sl@0
   604
		User::Leave(leaveCode);	
sl@0
   605
		}
sl@0
   606
	else
sl@0
   607
		{
sl@0
   608
		__PRINT(_L(" Added this information to the array\n"));
sl@0
   609
		__PRINT1(_L(" Number of elements in array=%d\n"),iDllArray->Count());
sl@0
   610
sl@0
   611
		}
sl@0
   612
	}
sl@0
   613
sl@0
   614
sl@0
   615
sl@0
   616
void CDllChecker::ListArray()
sl@0
   617
	{
sl@0
   618
	TInt elements=iDllArray->Count();
sl@0
   619
	
sl@0
   620
	CShell::TheConsole->Printf(_L(" Number of dependencies checked = %d\n"),elements);
sl@0
   621
sl@0
   622
	for (TInt i=0;i<elements; i++)
sl@0
   623
		{
sl@0
   624
//		Prints filename and result of CDllChecker::GetImportDataL for 
sl@0
   625
//		each element in iDllArray
sl@0
   626
#if defined (UNICODE)	
sl@0
   627
		TFileName filename;
sl@0
   628
		Get16BitDllName(iDllArray->At(i).iDllName,filename);
sl@0
   629
		CShell::TheConsole->Printf(_L(" %d: %-15S  Uid3: [%08x] "),(i+1),&(filename),(iDllArray->At(i).iUid));
sl@0
   630
#else
sl@0
   631
		CShell::TheConsole->Printf(_L(" %d: %-15S  Uid3: [%08x] "),(i+1),&(iDllArray->At(i).iDllName),(iDllArray->At(i).iUid));
sl@0
   632
#endif
sl@0
   633
		switch(iDllArray->At(i).iResult)
sl@0
   634
			{
sl@0
   635
		case(ENoImportData):
sl@0
   636
			CShell::TheConsole->Printf(_L("--- No import data\n"));
sl@0
   637
			break;
sl@0
   638
sl@0
   639
		case(EUidNotSupported):
sl@0
   640
			CShell::TheConsole->Printf(_L("--- Uid3 is not supported\n"));
sl@0
   641
			break;
sl@0
   642
sl@0
   643
		case(ENotFound):
sl@0
   644
			CShell::TheConsole->Printf(_L("--- File was not found\n"));
sl@0
   645
			break;
sl@0
   646
sl@0
   647
		case(ECouldNotOpenFile):
sl@0
   648
			CShell::TheConsole->Printf(_L("--- File could not be opened\n"));
sl@0
   649
			break;
sl@0
   650
sl@0
   651
		case(EUidDifference):
sl@0
   652
			CShell::TheConsole->Printf(_L("--- File already noted with different Uid\n"));
sl@0
   653
			break;
sl@0
   654
sl@0
   655
		case(EAlreadyOpen):
sl@0
   656
			CShell::TheConsole->Printf(_L("--- File already open\n"));
sl@0
   657
			break;
sl@0
   658
		
sl@0
   659
		case(EFileFoundAndUidSupported):
sl@0
   660
			CShell::TheConsole->Printf(_L("--- File was found, Uid3 is supported\n"));
sl@0
   661
			break;
sl@0
   662
		default:	//	Will never reach here
sl@0
   663
			CShell::TheConsole->Printf(_L("--- Undefined\n"));
sl@0
   664
			break;
sl@0
   665
			}
sl@0
   666
		}
sl@0
   667
	}
sl@0
   668