linklayercontrol/networkinterfacemgr/src/IF_MAN.CPP
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linklayercontrol/networkinterfacemgr/src/IF_MAN.CPP	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,403 @@
+// 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 "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:
+// Interface Manager
+// 
+//
+
+/**
+ @file IF_MAN.CPP
+*/
+
+#include "IF_DEF.H"
+#include "NI_STD.H"
+#include <es_mbman.h>
+#include "Ni_Log.h"
+#include <agentdialog.h>
+#include <c32root.h>
+#include <ecom/ecom.h>
+#include "cagentdlgproc.h"
+
+/**
+@internalComponent
+*/
+const TInt KAsyncDtorPriority = 10000;
+
+/**
+@internalComponent
+*/
+typedef CNifFactory* (*TNifFactoryNewL)();
+
+/**
+@internalComponent
+*/
+/*typedef CNetworkControllerBase* (*CreateNetConFunctionL)();*/
+
+inline TAny* Tls()
+/**
+@internalComponent
+*/
+ { return Dll::Tls(); }
+
+inline TInt SetTls(TAny* aTls) 
+/**
+@internalComponent
+*/
+{ return Dll::SetTls(aTls); }
+
+
+EXPORT_C CNifFactory::CNifFactory()
+/**
+Constructor
+*/
+	{
+
+	}
+
+EXPORT_C CNifFactory::~CNifFactory()
+/**
+Destructor
+*/
+	{
+
+	__ASSERT_DEBUG(!iLib.Handle(), Panic(ENifManPanic_LibraryNotClosed));
+	delete iAsyncDtor;
+	}
+
+
+EXPORT_C TInt CNifFactory::Open()
+/**
+If somehow something opens object just before it is destructed
+@return KErrNone,systemwide error code.
+*/
+	{
+	if(AccessCount()==0 && iAsyncDtor->IsActive())
+		iAsyncDtor->Cancel();
+	Inc();
+	return KErrNone;
+	}
+
+EXPORT_C void CNifFactory::Close()
+/**
+Defer deletion of object to facilitate async closing of library
+*/
+	{
+
+	Dec();
+	if (AccessCount()==0)
+		{
+		if(iAsyncDtor)
+			{
+			if(!iAsyncDtor->IsAdded())
+				{
+				CActiveScheduler::Add(iAsyncDtor);
+				}
+			iAsyncDtor->CallBack();
+			}
+		else // Only partially constructed
+			ControlledDelete(this);
+		}
+	}
+
+EXPORT_C TInt CNifFactory::ControlledDelete(TAny* aFactory)
+/**
+Delete factory
+@return systemwide error code
+*/
+	{
+	
+	CNifFactory* n = (CNifFactory*)aFactory;
+	RLibrary lib;
+	lib.SetHandle(n->iLib.Handle());
+	n->iLib.SetHandle(0);
+	delete n; // deletes async callback object also
+	lib.Close();
+	return KErrNone;
+	}
+
+EXPORT_C void CNifFactory::Cleanup(TAny* aObject)
+/**
+For use with clean up stack
+@param aObject
+*/
+	{
+	
+	((CObject*)aObject)->Close();
+	}
+
+EXPORT_C void CNifFactory::InitL(RLibrary& aLib, CObjectCon& aCon)
+/**
+Setup async Destructor & transfer library
+@param aLib
+@param aCon
+*/
+	{	
+	
+	TCallBack c = TCallBack(ControlledDelete, this);
+	iAsyncDtor = new (ELeave) CAsyncCallBack(c, KAsyncDtorPriority);
+	iAsyncDtor->Deque();	//PERF: we'll re-join the queue JIT
+	iLib.SetHandle(aLib.Handle());
+	aLib.SetHandle(0); // Handle transferred
+
+	TParse parse;
+	User::LeaveIfError(parse.Set(iLib.FileName(),0,0));
+	
+	TPtrC temp = parse.Name();
+	SetNameL(&temp);
+
+	InstallL(); // pure virtual
+	aCon.AddL(this);	
+	}
+
+
+//
+CNifMan::CNifMan()
+	{
+	}
+
+CNifMan::~CNifMan()
+	{
+
+	TInt i;
+
+	// go through deleting agents
+	CObjectCon* con;
+	if(iAgents)
+		{
+		con = iAgents;
+		for(i=0 ; i<con->Count() ; ++i)
+			delete (*con)[i];
+		}
+
+	// As all agents have been deleted there should be no factories left
+    // but as their d'tors are async they could still be lying around but
+	// access counts should be zero
+	// go through deleting factories for real
+
+	delete iAgentDlgProc;
+
+	if(iAgentFactories)
+		{
+		con = iAgentFactories;
+		for(i=0 ; i<con->Count() ; ++i)
+			delete (*con)[i];
+		}
+
+	if(iContainers)
+        {
+		delete iContainers;
+        }
+        
+	if(iDefMatch)
+        {
+		delete iDefMatch;
+        }
+        
+	if(iDefFilename)
+	    {
+		delete iDefFilename;
+	    }
+	    
+	if(Global()==this)
+	    {
+	    SetTls(NULL);
+	    }
+
+	// Unload the Dialog Server CPM
+	RRootServ rootserver;
+	if(rootserver.Connect()==KErrNone) 
+		{
+		TCFModuleName name;
+		name.Copy(KCommsDialogServerName);
+		TRequestStatus status;
+		rootserver.UnloadCpm(status, name, EImmediate);
+		User::WaitForRequest(status);
+		rootserver.Close();
+		}
+	
+	REComSession::FinalClose();
+	
+	LOG( NifmanLog::Printf(_L("--------------- Nifman Finished --------------")); )
+	}
+
+
+CAgentDialogProcessor* CNifMan::AgentDialogProcessor()
+    {
+    return iAgentDlgProc;
+    }
+
+
+void CNifMan::InstallL(const TDesC& /*aArgs*/)
+/**
+Treat as constructL() 
+Unless the bug has been fixed leaving will orphan a library handle
+so this is avoided at all costs by ensuring the extension is only ever loaded once
+*/
+	{
+
+	LOG( NifmanLog::Printf(_L("--------------- Nifman Started ---------------")); )
+	LOG_DETAILED( NifmanLog::Printf(_L("Detailed logging enabled")); )
+
+	if(Tls())
+		User::Leave(KErrAlreadyExists);
+
+	iContainers = CObjectConIx::NewL();
+	iAgents = iContainers->CreateL();
+	iAgentFactories = iContainers->CreateL();
+
+	iAgentDlgProc = new(ELeave)CAgentDialogProcessor();
+
+//	StartEsWatchThread();
+		
+	User::LeaveIfError(SetTls(this));
+	}
+
+void CNifMan::Remove()
+/**
+Let the destructor do it all
+*/
+	{
+	}
+
+EXPORT_C CNifMan* CNifMan::Global()
+/**
+Get the global nifman
+*/
+	{
+	return (CNifMan*)Tls();
+	}
+
+void CNifMan::DoGetFileNameL(const TDesC& aName, TDes& aFilename)
+/**
+Look in ini file for default agent module name
+*/
+	{
+
+	CESockIniData* ini=0;
+	TPtrC result;
+	
+	if(!iDefMatch || !iDefFilename)
+		{
+
+		ini = CESockIniData::NewL();
+	    CleanupStack::PushL(ini);
+		if(!iDefMatch)
+		    {
+		    if(!ini->FindVar(KNifManSection, KNifManDefault, result))
+				{
+				_LIT(genconnString,"genconn");
+			    iDefMatch = genconnString().AllocL();
+				}
+		    else
+			    iDefMatch = result.AllocL();
+			}
+
+		if(!iDefFilename)
+			{
+			if(!ini->FindVar(KNifManAgents, *iDefMatch, result))
+				{
+				TName name = *iDefMatch;
+				name.Append(KAgentExtension);
+				iDefFilename = name.AllocL();
+				}
+			else
+				iDefFilename = result.AllocL();
+			}
+		}
+
+	if(!aName.Length() || !aName.CompareF(*iDefMatch))
+		{
+		aFilename = *iDefFilename;
+		}
+	else
+		{
+		if(!ini)
+			{
+			ini = CESockIniData::NewL();
+	        CleanupStack::PushL(ini);
+			}
+		if(!ini->FindVar(KNifManAgents, aName, result))
+			{
+			aFilename=aName;
+
+			if(aFilename.Right(4) != KAgentExtension())
+				aFilename.Append(KAgentExtension);
+		    }
+		else
+		    aFilename = result;
+		}
+	
+	if(ini)
+		CleanupStack::PopAndDestroy();
+	}
+
+
+CNifFactory* CNifMan::DoFindFactoryL(TUid aUid2, const TDesC& aFilename, CObjectCon& aCon, TBool aCreate)
+/**
+Load a factory and check the Uid etc
+function always opens factory CObject if successful
+*/
+	{
+
+
+	TParse parse;
+	User::LeaveIfError(parse.Set(aFilename, 0, 0));
+
+	TName dummy1;
+	TInt find=0;
+	CNifFactory* f=0;
+
+	if(aCon.FindByName(find, parse.Name(), dummy1)!=KErrNone)
+		{
+
+		if(!aCreate)
+			User::Leave(KErrNotFound);
+
+	    // Else load the module
+		TAutoClose<RLibrary> lib;
+		User::LeaveIfError(lib.iObj.Load(aFilename));
+		lib.PushL();
+
+		// The Uid check
+		if(lib.iObj.Type()[1]!=aUid2)
+			User::Leave(KErrBadLibraryEntryPoint);
+
+		TNifFactoryNewL libEntry=(TNifFactoryNewL)lib.iObj.Lookup(1);
+		if (libEntry==NULL)
+			User::Leave(KErrNoMemory);
+
+		f =(*libEntry)(); // Opens CObject
+		if (!f)
+			User::Leave(KErrBadDriver);
+
+		CleanupStack::PushL(TCleanupItem(CNifFactory::Cleanup, f));
+		f->InitL(lib.iObj, aCon); // Transfers the library object if successful
+
+		// Can pop the library now - auto close will have no effect because handle is null
+		CleanupStack::Pop();
+		lib.Pop();
+
+		}
+	else
+		{
+		f=(CNifFactory*)aCon.At(find);
+		f->Open();
+		}
+	return f;
+	}
+
+
+TInt CNifMan::NumAgents() const
+	{
+	return iAgents->Count();
+	}