diff -r 000000000000 -r af10295192d8 linklayercontrol/networkinterfacemgr/src/IF_MAN.CPP --- /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 +#include "Ni_Log.h" +#include +#include +#include +#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 ; iCount() ; ++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 ; iCount() ; ++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 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(); + }