Esempio n. 1
0
//-----------------------------------------------------------------------------
//Function Name : void* __dlopen_r(const char* filename, int flag)
//Description   : To open the given dll filename.
//Return Value  : Valid handle value if no error, Null if dll couldn't be loaded 
//-----------------------------------------------------------------------------
void* __dlopen_r(const char* filename,const int flag)
	{
	//convert filename to TFileName
	TPtrC8 ptr8( (unsigned char*)filename);
	TFileName fileNameBuf;
	CnvUtfConverter::ConvertToUnicodeFromUtf8(fileNameBuf, ptr8);
	TParsePtr filePathName(fileNameBuf);
	
	//if file name contains wild character
	if ( filePathName.IsWild() )
		{
		SetError(KDlOpenErrNoSupport);
		return NULL;
		}
	//to load dll	
	RLibrary library;	
	TInt err;
	TBool isLibraryLoaded = EFalse;
	RFs fs;
	err = fs.Connect();
	if ( KErrNone == err )
		{
		TUint tempAtt;
		//if path is there load from this path
		if ( filePathName.PathPresent() )
			{
			err = fs.Att(filePathName.FullName(), tempAtt);
			fs.Close();	
			if ( KErrNotFound != err && KErrPathNotFound != err)
				{
				err = library.Load(filePathName.FullName());
				if ( KErrNone != err )
					{
					SetError(KDlOpenErrLoading);
					return NULL;
					}
				isLibraryLoaded = ETrue;	
				}
			}
		else//if there is no path its only file name
			{
			TPtrC fileName(filePathName.NameAndExt());
			char* envPathName = getenv("LD_LIBRARY_PATH");
			if ( envPathName )
				{
				TPtrC8 tempPtr8((unsigned char*)envPathName);
				TFileName envPathBuf;
				CnvUtfConverter::ConvertToUnicodeFromUtf8(envPathBuf, tempPtr8);
				TPtrC envPath(envPathBuf);
				TChar delim(';');
				TFileName fileToLoad;
				TInt pos = envPath.Locate(delim);
				//if delim does not found and still envPath contains value
				//i.e. this one is last path without delim(';') so take 
				//this also, for this length is checked
				while ( KErrNotFound != pos || envPath.Length())
					{
					//if there is no delim
					if (KErrNotFound == pos )
						{// so last path without delim
						pos = envPath.Length();
						}
					TPtrC thisPath(envPath.Left(pos));
					fileToLoad = thisPath;
					fileToLoad.Trim();
					//to check ";;" and ";   ;"
					if (fileToLoad.Length())
						{
						//if path does not conatin trailing \ add one
						if ( L'\\' != fileToLoad[fileToLoad.Length()-1] )
							{
							fileToLoad.Append(TChar(L'\\'));					
							}
						fileToLoad.Append(fileName);
					
						err = fs.Att(fileToLoad, tempAtt);
						if ( KErrNotFound != err && KErrPathNotFound != err)
							{
							//load file from this path
							err = library.Load(fileToLoad);
							if ( KErrNone == err )
								{
								// dll loaded successfully from thispath
								isLibraryLoaded = ETrue;	
								break;
								}	
							}
						}
					if ( pos == envPath.Length())		
						{
						break;
						}
					else
						{
						envPath.Set(envPath.Mid(pos + 1));
						}
					pos = envPath.Locate(delim);
					}
				fs.Close();	
				}
			else//load dll if only name is there and LD_LIBRARY_PATH path not set
				{
				fs.Close();	
				TInt err = library.Load(filePathName.NameAndExt());
				if ( KErrNone != err )
					{
					SetError(KDlOpenErrLoading);
					return NULL;
					}
				isLibraryLoaded = ETrue;		
				}
			}
	
		//if library is loaded	
		if ( isLibraryLoaded )	
			{
			//handle value to return 
			void* handle  = NULL;
			//lock list before any operation
			LoadedDlls()->Lock();
			//is this dll already there
			TInt listIdx = LoadedDlls()->Find(library);
			//if not already open
			if ( KErrNotFound == listIdx )
				{				
				TDllEntry dllEntry(library, flag);
				dllEntry.iSymbolHeader = (TE32ExpSymInfoHdr*)library.Lookup(0);
				
				err = dllEntry.iLibrary.Duplicate(RThread());	
				//Close the library irrespective of the result of duplicate
				library.Close();
				if ( KErrNone != err )
					{
					SetError(KDlOpenErrLoading);
					LoadedDlls()->UnLock();
					return NULL;
					}
				//add to list	
				err = LoadedDlls()->Add(dllEntry);
				handle = (void*) dllEntry.iLibrary.Handle();
				LoadedDlls()->UnLock();
				if ( KErrNone != err )
					{
					SetError(KDlOpenErrNoMemory);
					dllEntry.iLibrary.Close();
					return NULL;
					}
				}
			else//if this dll is already in list.
				{
				//close library we already have loaded
				library.Close();
				TDllEntry& dllEntry = LoadedDlls()->At(listIdx);
				//if flag is RTLD_GLOBAL store it otherwise ignore
				//as RTLD_LAZY and RTLD_NOW both means RTLD_NOW
				//so can be ignored. RTLD_LOCAL does not change previous flag
				if ( flag & RTLD_GLOBAL )
					{
					dllEntry.iFlags |= RTLD_GLOBAL;
					}
				dllEntry.iRefCount++;	
				handle = (void*) dllEntry.iLibrary.Handle();
				LoadedDlls()->UnLock();	
				}	
			return handle;			
			}
		}
	SetError(KDlOpenErrLoading);
	return NULL;		
	}