commsfwsupport/commselements/rootserver/rootsrv/rootsess.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2003-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 "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 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include "rsstd.h"
       
    22 #include "bindmgr.h"
       
    23 #include <elements/cfmacro.h>
       
    24 #include <cflog.h>
       
    25 
       
    26 __CFLOG_STMT(_LIT8(KLogSubSysRS, "RootServer");) // subsystem name
       
    27 
       
    28 EXPORT_C CRootServerSession::CRootServerSession(const CRootServer* aRootServer)
       
    29     :iActiveHandlers(_FOFF(CSessionHandler, iLink))
       
    30     {
       
    31     iRootServer = (CRootServer*) aRootServer;
       
    32     }
       
    33 
       
    34 TInt CRootServerSession::CancelLoadCPM(const RMessage2& aMessage)
       
    35     /** Attempt to cancel a load cpm request.
       
    36      If a pending request is not found, we check that the module
       
    37 	 is running already.  We cannot actually cancel a request as we cannot
       
    38 	 guarantee that it will not be completed just after we delete the request,
       
    39 	 which will therefore lead to a stray event - bad!
       
    40      @internalComponent
       
    41      @param aMessage The message which will be completed.
       
    42      @return Whether the function was successful or not.
       
    43      */
       
    44     {
       
    45     TCFModuleNameF name;
       
    46     TInt result = aMessage.Read(0, name);
       
    47     if(result==KErrNone)
       
    48 		{
       
    49 		__CFLOG_1(KLogSubSysRS, KLogCode, _L8("CRootServerSession - CancelLoadCPM: %S"), &name);
       
    50 		}
       
    51 	else
       
    52 		{
       
    53 		__CFLOG_1(KLogSubSysRS, KLogCode, _L8("CRootServerSession - CancelLoadCPM: error %d reading module name"), result);
       
    54         return result;
       
    55 		}
       
    56 
       
    57 	TDblQueIter<CSessionHandler> handlerIter(iActiveHandlers);
       
    58     CSessionHandler* handler;
       
    59 	result = KErrNotFound;
       
    60     while(result != KErrNone && (handler = handlerIter++) != NULL)
       
    61         {
       
    62 		if(handler->HandlerType() == CSessionHandler::ESHTypeLoadCPM)
       
    63 			{
       
    64 			CSessionHandlerLoadCPM* loadHandler = static_cast<CSessionHandlerLoadCPM*>(handler);
       
    65 			if(loadHandler->MatchPending(name))
       
    66 				{
       
    67 				// Complete with KErrCancel
       
    68 				if(loadHandler->CancelHandler(ETrue))
       
    69 					{
       
    70 					delete loadHandler;
       
    71 					}
       
    72 				result = KErrNone;
       
    73 				}
       
    74 			}
       
    75         }
       
    76 
       
    77     return result;
       
    78     }
       
    79 
       
    80 TInt CRootServerSession::LoadCPML(const RMessage2& aMessage)
       
    81     /** Load a module.
       
    82      Generic load function for both servers and providers.  Simply reads data from
       
    83 	 message and uses aModuleRequest to decide which type of load to kick off
       
    84      @internalComponent
       
    85      @param aMessage The message which will be completed.
       
    86      @return Whether the function was successful or not.
       
    87      */
       
    88 	{
       
    89 
       
    90 	iMessage = aMessage;
       
    91     TRSStartModuleParams params;
       
    92 	aMessage.ReadL(0, params);
       
    93 
       
    94 	__CFLOG_1(KLogSubSysRSModule, KLogCode, _L8("CRootServerSession - LoadCPML: %S"), &params.iParams.iName);
       
    95 
       
    96     if((params.iParams.iName.Length()>KCFMaxModuleName) ||
       
    97        (params.iParams.iName.Length()<1) ||	// magic number 1 - name must have at least one character
       
    98        (params.iParams.iName.MaxLength()!=KCFMaxModuleName))
       
    99         {
       
   100         return (KErrRSInvalidParameterName);
       
   101         }
       
   102 
       
   103     if((params.iParams.iFilename.Length()>KMaxFileName) ||
       
   104        (params.iParams.iFilename.Length()<5) || // magic number 5 - one character plus "." plus 3 letter file extension
       
   105        (params.iParams.iFilename.MaxLength()!=KMaxFileName))
       
   106         {
       
   107         return (KErrRSInvalidParameterFile);
       
   108         }
       
   109 
       
   110     if(params.iParams.iThreadFunctionOrdinal<0)
       
   111         {
       
   112         return (KErrRSInvalidParameterThreadFuncOrdinal);
       
   113         }
       
   114 
       
   115     if(params.iParams.iStackSize<0)
       
   116         {
       
   117         return (KErrRSInvalidParameterStackSize);
       
   118         }
       
   119 
       
   120 	if(params.iParams.iHeapType==ENewHeap)
       
   121 		{
       
   122 		if(params.iParams.iMinHeapSize<KMinHeapSize)
       
   123     		{
       
   124     		return (KErrRSInvalidParameterHeapSize);
       
   125     		}
       
   126 		if(params.iParams.iMaxHeapSize<params.iParams.iMinHeapSize)
       
   127     		{
       
   128     		return (KErrRSInvalidParameterHeapSize);
       
   129     		}
       
   130 		}
       
   131 
       
   132     HBufC8* inidata = NULL;
       
   133   	TInt size = 0;
       
   134 	if(aMessage.Ptr1())
       
   135 		{
       
   136 	  	size = aMessage.GetDesLength(1);
       
   137 		User::LeaveIfError(size);
       
   138 		}
       
   139 
       
   140   	if (size>0)
       
   141   		{
       
   142   		inidata = HBufC8::NewLC(size);
       
   143     	TPtr8 tpInidata(inidata->Des());
       
   144     	aMessage.ReadL(1, tpInidata);
       
   145     	}
       
   146 
       
   147 	__CFLOG(KLogSubSysRS, KLogCode,
       
   148 				_L8("CRootServerSession - Load request in LoadModuleL"));
       
   149 	iRootServer->LazyLoadL();
       
   150 	CCommsProviderModule* pModule = iRootServer->CreateCpmL(params, inidata);
       
   151 	if(inidata)
       
   152 		{
       
   153 		CleanupStack::Pop(inidata);
       
   154 		}
       
   155 	CleanupStack::PushL(pModule);
       
   156 	pModule->CreateThreadL();
       
   157 
       
   158 	CSessionHandlerLoadCPM* pHandler =
       
   159 			CSessionHandlerLoadCPM::NewL(this, iRootServer->BindManager(), aMessage);
       
   160 	RegisterHandler(*pHandler);
       
   161 	pHandler->SetHandler(pModule->GetName());
       
   162 	TInt result = pHandler->Start();
       
   163 	CleanupStack::Pop(pModule);	// pModule
       
   164 
       
   165 	return result;
       
   166     }
       
   167 
       
   168 TInt CRootServerSession::CancelUnloadCPM(const RMessage2& aMessage)
       
   169     /** Cancel an unload cpm request.
       
   170      If a pending unload request is found, then we still
       
   171 	 cannot cancel it, otherwise we may have a stray event as we
       
   172 	 cannot guarantee that the request would not be completed
       
   173 	 just after we attempt to cancel it.
       
   174      @internalComponent
       
   175      @param aMessage The message which will be completed.
       
   176      @return Whether the function was successful or not.
       
   177      */
       
   178 	{
       
   179 
       
   180     TCFModuleNameF name;
       
   181     TInt result = aMessage.Read(0, name);
       
   182     if(result==KErrNone)
       
   183 		{
       
   184 		__CFLOG_1(KLogSubSysRS, KLogCode, _L8("CRootServerSession - CancelUnloadCPM: %S"), &name);
       
   185 		}
       
   186 	else
       
   187 		{
       
   188 		__CFLOG_1(KLogSubSysRS, KLogCode, _L8("CRootServerSession - CancelUnloadCPM: error %d reading module name"), result);
       
   189         return result;
       
   190 		}
       
   191 
       
   192 	TDblQueIter<CSessionHandler> handlerIter(iActiveHandlers);
       
   193     CSessionHandler* handler;
       
   194 	result = KErrNotFound;
       
   195     while(result != KErrNone && (handler = handlerIter++) != NULL)
       
   196         {
       
   197 		if(handler->HandlerType() == CSessionHandler::ESHTypeUnLoadCPM)
       
   198 			{
       
   199 			CSessionHandlerUnLoadCPM* unLoadHandler = static_cast<CSessionHandlerUnLoadCPM*>(handler);
       
   200 			if(unLoadHandler->MatchPending(name))
       
   201 				{
       
   202 				// Complete with KErrCancel
       
   203 				if(unLoadHandler->CancelHandler(ETrue))
       
   204 					{
       
   205 					delete unLoadHandler;
       
   206 					}
       
   207 				result = KErrNone;
       
   208 				}
       
   209 			}
       
   210         }
       
   211         
       
   212     #ifdef __CFLOG_ACTIVE
       
   213 	    if(result != KErrNone)
       
   214 	    	{
       
   215 	 		__CFLOG_2(KLogSubSysRS, KLogCode, _L8("CRootServerSession::CancelUnloadCPM - error %d trying to cancel unload of module %S"), result, &name);
       
   216 	 	  	}
       
   217 	#endif
       
   218 
       
   219     return result;
       
   220 	}
       
   221 
       
   222 TInt CRootServerSession::UnloadCPML(const RMessage2& aMessage)
       
   223     /** Unload a cpm.
       
   224      If the cpm requested to unload is found, then
       
   225 	 the bindmgr is called to shutdown the module
       
   226      @internalComponent
       
   227      @param aMessage The message which will be completed.
       
   228      @return TInt - whether the function was successful or not.
       
   229      */
       
   230     {
       
   231 	CCommsProviderModule* pModule = NULL;
       
   232 
       
   233     TCFModuleNameF name;
       
   234     aMessage.ReadL(0, name);
       
   235 	TRSUnLoadType unloadType = (TRSUnLoadType) aMessage.Int1();
       
   236 	
       
   237 	#if defined _DEBUG || defined __CFLOG_ACTIVE || defined SYMBIAN_TRACE_ENABLE
       
   238 		TPtrC8 unloadTypePtr = CCommsProviderModule::GetUnloadTypeName(unloadType);
       
   239 
       
   240 		__CFLOG_2(KLogSubSysRS, KLogCode, _L8("CRootServerSession - UnloadCPML: %S, unload type %S"), &name, &unloadTypePtr);
       
   241 
       
   242 		// Warn the programmer that forced module unloads are unsafe.
       
   243 		if((unloadType == EImmediate) || (unloadType == EUnGraceful))
       
   244 			{
       
   245 			_LIT8(KForcedModuleUnloadWarning, "WARNING: An %S unload of the %S module has been initiated.  This may cause panics or memory leaks/corruption, especially if any sessions are still open. Any error reported from now until server shutdown may be spurious.");
       
   246 			
       
   247 			#ifdef _DEBUG
       
   248 				RDebug::Printf(reinterpret_cast<const char *>(TPtrC8(KForcedModuleUnloadWarning).Ptr()), &unloadTypePtr, &name);
       
   249 			#endif
       
   250 			
       
   251 			// Log the warning to UTrace if available.
       
   252 			#ifdef SYMBIAN_TRACE_ENABLE
       
   253 			    enum
       
   254 			        {
       
   255 			        KPrimaryFilter = 194, // server den
       
   256 			        KMaxLogTextLength = 250
       
   257 			        };
       
   258 
       
   259 			    class TLogIgnoreOverflow8 : public TDes8Overflow
       
   260 			        {
       
   261 			        public:
       
   262 			            void Overflow(TDes8& /*aDes*/) { }
       
   263 			        };
       
   264 
       
   265 				// Format the log text into a buffer for UTrace.
       
   266 			    TBuf8<KMaxLogTextLength> buf;
       
   267 		    	TLogIgnoreOverflow8 overflowHandler;
       
   268 			    buf.AppendFormat(KForcedModuleUnloadWarning, &overflowHandler, &unloadTypePtr, &name);
       
   269 
       
   270 				UTracePfAny(KPrimaryFilter, KText, ETrue, EFalse, buf.Length(), buf.Ptr(), buf.Length());
       
   271 			#endif
       
   272 
       
   273 			__CFLOG_2(KLogSubSysRS, KLogCode, KForcedModuleUnloadWarning, &unloadTypePtr, &name);
       
   274 			}
       
   275 	#endif
       
   276 
       
   277 	pModule = iRootServer->FindCpm(name);
       
   278 	if( !pModule )
       
   279 		{
       
   280 		__CFLOG(KLogSubSysRS, KLogCode, _L8("Couldn't find cpm"));
       
   281 		return KErrRSModuleNotLoaded;
       
   282 		}
       
   283 
       
   284 	if(pModule->IsSticky())
       
   285 		{
       
   286 		return KErrLocked;
       
   287 		}
       
   288 
       
   289 	CSessionHandlerUnLoadCPM* pHandler =
       
   290 			CSessionHandlerUnLoadCPM::NewL(this, iRootServer->BindManager(), aMessage);
       
   291 	RegisterHandler(*pHandler);
       
   292 	pHandler->SetHandler(pModule->GetName(), unloadType);
       
   293 
       
   294 	return pHandler->Start();
       
   295     }
       
   296 
       
   297 TInt CRootServerSession::CancelBind(const RMessage2& aMessage)
       
   298     /** Cancel a bind request.
       
   299      Attempt to cancel a pending bind request between two modules. Simply
       
   300 	 looks for a match in the list of pending session handler requests.
       
   301      @internalComponent
       
   302      @param aMessage The message which will be completed.
       
   303      @return TInt - whether the function was successful or not.
       
   304      */
       
   305 	{
       
   306 	__CFLOG(KLogSubSysRS, KLogCode, _L8("CRootSession - CancelBind"));
       
   307 
       
   308 	TRSSubModuleAddress binfo;
       
   309 	TInt result = aMessage.Read(0, binfo);
       
   310     if(result!=KErrNone)
       
   311     	{
       
   312         return result;
       
   313         }
       
   314 
       
   315 	TCFSubModuleAddress moduleFrom = binfo.iAddress;
       
   316 
       
   317 	result = aMessage.Read(1, binfo);
       
   318     if(result!=KErrNone)
       
   319 	    {
       
   320         return result;
       
   321         }
       
   322 
       
   323 	TCFSubModuleAddress moduleTo = binfo.iAddress;
       
   324 
       
   325 	if(moduleFrom.Module().Length()>KCFMaxModuleName)
       
   326 		{
       
   327 		return KErrBadName;
       
   328 		}
       
   329 
       
   330 	if(moduleTo.Module().Length()>KCFMaxModuleName)
       
   331 		{
       
   332 		return KErrBadName;
       
   333 		}
       
   334 
       
   335 	TDblQueIter<CSessionHandler> handlerIter(iActiveHandlers);
       
   336     CSessionHandler* handler;
       
   337 	result = KErrNotFound;
       
   338     while(result != KErrNone && (handler = handlerIter++) != NULL)
       
   339         {
       
   340 		if(handler->HandlerType() == CSessionHandler::ESHTypeBinding)
       
   341 			{
       
   342 			CSessionHandlerBinding* bindingHandler = static_cast<CSessionHandlerBinding*>(handler);
       
   343 			if(bindingHandler->MatchPending(moduleFrom, moduleTo))
       
   344 				{
       
   345 				// Complete with KErrCancel
       
   346 				bindingHandler->Cancel();
       
   347 				result = KErrNone;
       
   348 				}
       
   349 			}
       
   350         }
       
   351     return result;
       
   352 	}
       
   353 
       
   354 TInt CRootServerSession::BindL(const RMessage2& aMessage)
       
   355     /** Bind two submodules.
       
   356      Binds two modules together by prompting the binding manager in the right way.
       
   357 	 If the top module is a server, then the bind type must be a hierarchical bind!
       
   358      @internalComponent
       
   359      @param aMessage The message which will be completed.
       
   360      @return TInt - whether the function was successful or not.
       
   361      */
       
   362     {
       
   363 
       
   364 	TRSBindingInfo params;
       
   365 	aMessage.ReadL(0, params);
       
   366  
       
   367 	TCFSubModuleAddress moduleFrom(params.iParams.iAddress1);
       
   368 	TCFSubModuleAddress moduleTo(params.iParams.iAddress2);
       
   369 	TRSBindType bindType = params.iParams.iType;
       
   370 
       
   371     __CFLOG_3(KLogSubSysRS, KLogCode,_L8("CRootServerSession - BindL: binding %S with %S, bind type %d"), &moduleFrom, &moduleTo, bindType);
       
   372 
       
   373 	if(moduleFrom.Module().Length() > KCFMaxModuleName)
       
   374 		{
       
   375 	    __CFLOG(KLogSubSysRS, KLogCode,_L8("CRootServerSession - BindL KErrBadName"));
       
   376 		return KErrBadName;
       
   377 		}
       
   378 
       
   379 	if(moduleFrom.SubModule().Length() > KCFMaxSubModuleName)
       
   380 		{
       
   381 	    __CFLOG(KLogSubSysRS, KLogCode,_L8("CRootServerSession - BindL KErrBadName"));
       
   382 		return KErrBadName;
       
   383 		}
       
   384 
       
   385 	if(moduleTo.Module().Length() > KCFMaxModuleName)
       
   386 		{
       
   387 	    __CFLOG(KLogSubSysRS, KLogCode,_L8("CRootServerSession - BindL KErrBadName"));
       
   388 		return KErrBadName;
       
   389 		}
       
   390 
       
   391 	if(moduleTo.SubModule().Length() > KCFMaxSubModuleName)
       
   392 		{
       
   393 	    __CFLOG(KLogSubSysRS, KLogCode,_L8("CRootServerSession - BindL KErrBadName"));
       
   394 		return KErrBadName;
       
   395 		}
       
   396 
       
   397 	if(params.iParams.iForwardQLength < TRSBindingInfo::EMinQueueLength ||
       
   398 	   params.iParams.iReverseQLength < TRSBindingInfo::EMinQueueLength ||
       
   399 	   params.iParams.iForwardQLength > TRSBindingInfo::EMaxQueueLength ||
       
   400 	   params.iParams.iReverseQLength > TRSBindingInfo::EMaxQueueLength)
       
   401 		{
       
   402 	    __CFLOG(KLogSubSysRS, KLogCode,_L8("CRootServerSession - BindL KErrRSInvalidQueueLength"));
       
   403 		return KErrRSInvalidQueueLength;
       
   404 		}
       
   405 
       
   406    __CFLOG_4(KLogSubSysRS, KLogCode,_L8("CRootServerSession. Binding %S with %S. Queues[%d,%d]"), &moduleFrom, &moduleTo, params.iParams.iForwardQLength, params.iParams.iReverseQLength);
       
   407 
       
   408 	// do checking here
       
   409 	CCommsProviderModule* pModuleFrom = iRootServer->FindCpm(moduleFrom.Module());
       
   410 	CCommsProviderModule* pModuleTo = iRootServer->FindCpm(moduleTo.Module());
       
   411 	if( !pModuleFrom )
       
   412 		{
       
   413 		return KErrRSModuleNotLoaded;
       
   414 		}
       
   415 	if( !pModuleTo )
       
   416 		{
       
   417 		return KErrRSModuleNotLoaded;
       
   418 		}
       
   419 	if(bindType == EHierarchical && pModuleTo->IsServer())
       
   420 		{
       
   421 		return KErrRSInvalidBinding;
       
   422 		}
       
   423 
       
   424 	CSessionHandlerBinding* pHandler =
       
   425 			CSessionHandlerBinding::NewL(this, iRootServer->BindManager(), aMessage);
       
   426 	RegisterHandler( *pHandler );
       
   427 
       
   428 	pHandler->SetHandler(moduleFrom, moduleTo, bindType,
       
   429 	  					 params.iParams.iForwardQLength,
       
   430 						 params.iParams.iReverseQLength);
       
   431 
       
   432     return pHandler->Start();
       
   433     }
       
   434 
       
   435 TInt CRootServerSession::CancelUnbind(const RMessage2& aMessage)
       
   436     /** Cancel an unbind request.
       
   437      Attempt to cancel a previous request to unbind two submodules.
       
   438 	 Again tries to match a pending session handler request.
       
   439      @internalComponent
       
   440      @param aMessage The message which will be completed.
       
   441      @return Whether the function was successful or not.
       
   442      */
       
   443 	{
       
   444 
       
   445 	__CFLOG(KLogSubSysRS, KLogCode, _L8("CRootServerSession - CancelUnbind"));
       
   446 
       
   447 	TRSSubModuleAddress binfo;
       
   448 	TInt result = aMessage.Read(0, binfo);
       
   449     if(result!=KErrNone)
       
   450     	{
       
   451         return result;
       
   452         }
       
   453 
       
   454 	TCFSubModuleAddress moduleFrom = binfo.iAddress;
       
   455 	result = aMessage.Read(1, binfo);
       
   456     if(result!=KErrNone)
       
   457     	{
       
   458         return result;
       
   459         }
       
   460 
       
   461 	TCFSubModuleAddress moduleTo = binfo.iAddress;
       
   462 
       
   463 	if(moduleFrom.Module().Length()>KCFMaxModuleName)
       
   464 		{
       
   465 		return KErrBadName;
       
   466 		}
       
   467 
       
   468 	if(moduleTo.Module().Length()>KCFMaxModuleName)
       
   469 		{
       
   470 		return KErrBadName;
       
   471 		}
       
   472 
       
   473 	TDblQueIter<CSessionHandler> handlerIter(iActiveHandlers);
       
   474     CSessionHandler* handler;
       
   475 	result = KErrNotFound;
       
   476     while(result != KErrNone && (handler = handlerIter++) != NULL)
       
   477         {
       
   478 		if(handler->HandlerType() == CSessionHandler::ESHTypeUnBinding)
       
   479 			{
       
   480 			CSessionHandlerUnBinding* unbindingHandler = static_cast<CSessionHandlerUnBinding*>(handler);
       
   481 			if(unbindingHandler->MatchPending(moduleFrom, moduleTo))
       
   482 				{
       
   483 				// Complete with KErrCancel
       
   484 				unbindingHandler->Cancel();
       
   485 				result = KErrNone;
       
   486 				}
       
   487 			}
       
   488         }
       
   489 
       
   490     return result;
       
   491 	}
       
   492 
       
   493 TInt CRootServerSession::UnbindL(const RMessage2& aMessage)
       
   494     /** Unbind two submodules.
       
   495      Unbinds two modules by asking the bind manager to deal with request.
       
   496 	 Uses rootserver findProvider() and findServer() functions to check if requested modules are loaded
       
   497      @internalComponent
       
   498      @param aMessage The message which will be completed.
       
   499      @return Whether the function was successful or not.
       
   500      */
       
   501     {
       
   502     __CFLOG(KLogSubSysRS, KLogCode,_L8("CRootServerSession - Unbind"));
       
   503 
       
   504 	TRSUnBindingInfo params;
       
   505 	aMessage.ReadL( 0, params );
       
   506 
       
   507 	TCFSubModuleAddress moduleFrom = params.iParams.iAddress1;
       
   508 	TCFSubModuleAddress moduleTo = params.iParams.iAddress2;
       
   509 
       
   510 	if(moduleFrom.Module().Length()>KCFMaxModuleName)
       
   511 		{
       
   512 		return KErrBadName;
       
   513 		}
       
   514 
       
   515 	if(moduleTo.Module().Length()>KCFMaxModuleName)
       
   516 		{
       
   517 		return KErrBadName;
       
   518 		}
       
   519 
       
   520 	// do checking here
       
   521 	CCommsProviderModule* pModuleFrom = iRootServer->FindCpm(moduleFrom.Module());
       
   522 	CCommsProviderModule* pModuleTo = iRootServer->FindCpm(moduleTo.Module());
       
   523 
       
   524 	if((!pModuleFrom) || (!pModuleTo))
       
   525 		{
       
   526 		return KErrRSModuleNotLoaded;
       
   527 		}
       
   528 
       
   529 	CSessionHandlerUnBinding* pHandler =
       
   530 			CSessionHandlerUnBinding::NewL(this, iRootServer->BindManager(), aMessage);
       
   531 	RegisterHandler(*pHandler);
       
   532 	pHandler->SetHandler(moduleFrom, moduleTo);
       
   533 
       
   534     return pHandler->Start();
       
   535     }
       
   536 
       
   537 TInt CRootServerSession::EnumerateBindings(const RMessage2& aMessage)
       
   538     /** Get binding info for a module.
       
   539      We fill a descriptor with bindInfo objects
       
   540      @internalComponent
       
   541      @param aMessage The message to be filled with bindInfo.
       
   542      @return Whether the function was successful or not.
       
   543      */
       
   544 
       
   545     {
       
   546 	TRSSubModuleAddress moduleAddr;
       
   547 	TInt result = aMessage.Read(0, moduleAddr);
       
   548 	if(KErrNone == result)
       
   549 		{
       
   550 		TPckgBuf<TRSIter> ipcPosition;
       
   551 		result = aMessage.Read(1, ipcPosition);
       
   552 		if(KErrNone == result)
       
   553 			{
       
   554 			TInt& position = ipcPosition()();
       
   555 			// Locate the right one
       
   556 			CBindManager* const bindMgr = iRootServer->BindManager();
       
   557 			CBindManager::TBindingInfo info;
       
   558 			result = bindMgr->EnumerateBindings(moduleAddr.iAddress, ETrue, info);
       
   559 			for(TInt cursor = 0; (cursor < position) && (KErrNone == result); cursor++)
       
   560 				{
       
   561 				result = bindMgr->EnumerateBindings(moduleAddr.iAddress, EFalse, info);
       
   562 				}
       
   563 			if(KErrNone == result)
       
   564        			{
       
   565 				// Got one, copy the information to the client
       
   566 				TRSBindingInfo bindInfo;
       
   567 				bindInfo.iParams.iType = info.iType;
       
   568 				bindInfo.iParams.iAddress1 = info.iSubModuleAddr1;
       
   569 				bindInfo.iParams.iAddress2 = info.iSubModuleAddr2;
       
   570 				bindInfo.iParams.iState1 = info.iSubModuleState1;
       
   571 				bindInfo.iParams.iState2 = info.iSubModuleState2;
       
   572 				result = aMessage.Write(2, bindInfo);
       
   573 				if(KErrNone == result)
       
   574        				{
       
   575 					++position;
       
   576 					result = aMessage.Write(1, ipcPosition);
       
   577 					}
       
   578 				}
       
   579 			}
       
   580 		}
       
   581 	return result;
       
   582 	}
       
   583 
       
   584 
       
   585 TInt CRootServerSession::GetModuleInfo(const RMessage2& aMessage)
       
   586     /** Get info for a module.
       
   587      Fills a descriptor with information regarding the
       
   588 	 module specified in the message
       
   589      @internalComponent
       
   590      @param aMessage The message to be filled with moduleInfo.
       
   591      @return Whether the function was successful or not.
       
   592      */
       
   593     {
       
   594     TCFModuleNameF name;
       
   595     TRSModuleInfo info;
       
   596     TInt result = aMessage.Read(0, name);
       
   597     if(result!=KErrNone)
       
   598         {
       
   599         return result;
       
   600         }
       
   601 
       
   602 	if(name.Length()>KCFMaxModuleName)
       
   603 		{
       
   604 		return KErrBadName;
       
   605 		}
       
   606 
       
   607     result = iRootServer->GetModuleInfo(name, info);
       
   608 
       
   609     if(result!=KErrNone)
       
   610         {
       
   611         return result;
       
   612         }
       
   613   	result = aMessage.Write(1, info);
       
   614     return result;
       
   615     }
       
   616 
       
   617 TInt CRootServerSession::EnumerateModules(const RMessage2& aMessage)
       
   618     /** Enumerate the rootserver.
       
   619      Finds loaded modules in the root server and fills a descriptor
       
   620 	 list in the message
       
   621      @internalComponent
       
   622      @param aMessage The client message.
       
   623      @return Whether the function was successful or not.
       
   624 	 */
       
   625     {
       
   626 	TPckgBuf<TRSIter> ipcPosition;
       
   627 	TInt result = aMessage.Read(0, ipcPosition);
       
   628 	if(KErrNone == result)
       
   629 		{
       
   630 		TInt& position = ipcPosition()();
       
   631 
       
   632 		TCFModuleNameF moduleName;
       
   633 		result = iRootServer->EnumerateModules(position, moduleName);
       
   634 		if(KErrNone == result)
       
   635        		{
       
   636 			result = aMessage.Write(1, moduleName);
       
   637 			if(KErrNone == result)
       
   638        			{
       
   639 				++position;
       
   640 				result = aMessage.Write(0, ipcPosition);
       
   641 				}
       
   642 			}
       
   643 		}
       
   644     return result;
       
   645     }
       
   646 
       
   647 TInt CRootServerSession::EnumerateSubModules(const RMessage2& aMessage)
       
   648     /** Enumerate the rootserver.
       
   649      Finds loaded modules in the root server and fills a descriptor
       
   650 	 list in the message
       
   651      @internalComponent
       
   652      @param aMessage The message to be filled with list of modules found.
       
   653      @return Whether the function was successful or not.
       
   654      */
       
   655     {
       
   656 	TCFModuleNameF moduleName;
       
   657 	TInt result = aMessage.Read(0, moduleName);
       
   658 	if(KErrNone == result)
       
   659 		{
       
   660 		if(!iRootServer->FindCpm(moduleName))
       
   661 			{
       
   662  			return KErrNotFound;
       
   663  			}
       
   664 		TPckgBuf<TRSIter> ipcPosition;
       
   665 		result = aMessage.Read(1, ipcPosition);
       
   666 		if(KErrNone == result)
       
   667 			{
       
   668 			TInt& position = ipcPosition()();
       
   669 		    TCFSubModuleNameF subModuleName;
       
   670 			result = iRootServer->EnumerateSubModules(moduleName, position, subModuleName);
       
   671 			if(KErrNone == result)
       
   672        			{
       
   673 				result = aMessage.Write(2, subModuleName);
       
   674 				if(KErrNone == result)
       
   675        				{
       
   676 					++position;
       
   677 					result = aMessage.Write(1, ipcPosition);
       
   678 					}
       
   679 				}
       
   680 			}
       
   681 		}
       
   682 	return result;
       
   683 	}
       
   684 
       
   685 EXPORT_C void CRootServerSession::ServiceL(const RMessage2& aMessage)
       
   686 	/** Messages are handled here.
       
   687 	 @internalComponent
       
   688 	 */
       
   689     {
       
   690 
       
   691     TInt result = KErrGeneral;
       
   692     TBool completeNow = ETrue;
       
   693     switch ((aMessage.Function()))
       
   694 		{
       
   695 		case RSIsCallerConfigurator:
       
   696 			result = IsCallerConfigurator(aMessage);
       
   697 			break;
       
   698 
       
   699 		case RSLoadModule:
       
   700 			TRAP(result, result = LoadCPML(aMessage));
       
   701 			
       
   702 			#ifdef __CFLOG_ACTIVE
       
   703 				if( result != KErrNone )
       
   704 					{
       
   705 					__CFLOG_1(KLogSubSysRS, KLogCode, _L8("CRootServerSession::ServiceL: RSLoadModule - error %d starting to load CPM"), result);
       
   706 					}
       
   707 			#endif
       
   708 			
       
   709 			completeNow = (result != KErrNone);
       
   710 			break;
       
   711 		case RSUnloadModule:
       
   712 			TRAP(result, result = UnloadCPML(aMessage));
       
   713 			
       
   714 			#ifdef __CFLOG_ACTIVE
       
   715 				if( result != KErrNone )
       
   716 					{
       
   717 					__CFLOG_1(KLogSubSysRS, KLogCode, _L8("CRootServerSession::ServiceL: RSUnloadModule - error %d starting to unload CPM"), result);
       
   718 					}
       
   719 			#endif
       
   720 			
       
   721 			completeNow = (result != KErrNone);
       
   722 			break;
       
   723 		case RSGetModuleInfo:
       
   724 			result = GetModuleInfo(aMessage);
       
   725 			break;
       
   726 		case RSEnumerateModules:
       
   727 			result = EnumerateModules(aMessage);
       
   728 			break;
       
   729 		case RSEnumerateSubModules:
       
   730 			result = EnumerateSubModules(aMessage);
       
   731 			break;
       
   732 
       
   733 		case RSCancelLoadModule:
       
   734 			result = CancelLoadCPM(aMessage);
       
   735 			break;
       
   736 		case RSCancelUnloadModule:
       
   737 			result = CancelUnloadCPM(aMessage);
       
   738 			break;
       
   739 		case RSCloseSession:
       
   740 			CloseSession();
       
   741 			result = KErrNone;
       
   742 			break;
       
   743 		case RSShutdown:
       
   744 			result = Shutdown();
       
   745 			break;
       
   746 		case RSSendMessage:
       
   747 			result = Forward( aMessage );
       
   748 			completeNow = (result != KErrNone);
       
   749 			break;
       
   750 		case RSBind:
       
   751 			TRAP(result, result = BindL(aMessage));
       
   752 			
       
   753 			#ifdef __CFLOG_ACTIVE
       
   754 				if( result != KErrNone )
       
   755 					{
       
   756 					__CFLOG_1(KLogSubSysRS, KLogCode, _L8("CRootServerSession::ServiceL: RSBind - error %d starting to bind modules"), result);
       
   757 					}
       
   758 			#endif
       
   759 			
       
   760 			completeNow = (result != KErrNone);
       
   761 			break;
       
   762 		case RSUnbind:
       
   763 			TRAP(result, result = UnbindL(aMessage));
       
   764 			
       
   765 			#ifdef __CFLOG_ACTIVE
       
   766 				if( result != KErrNone )
       
   767 					{
       
   768 					__CFLOG_1(KLogSubSysRS, KLogCode, _L8("CRootServerSession::ServiceL: RSUnbind - error %d starting to unbind modules"), result);
       
   769 					}
       
   770 			#endif
       
   771 			
       
   772 			completeNow = (result != KErrNone);
       
   773 			break;
       
   774 		case RSEnumerateBindings:
       
   775 			result = EnumerateBindings(aMessage);
       
   776 			break;
       
   777 		case RSCancelBind:
       
   778 			result = CancelBind(aMessage);
       
   779 			break;
       
   780 		case RSCancelUnbind:
       
   781 			result = CancelUnbind(aMessage);
       
   782 			break;
       
   783 
       
   784 			// Server debug messages
       
   785 #if defined (_DEBUG_ROOTSERVER_FUNCTIONS)	// {
       
   786 		case RSDbgMarkHeap:
       
   787 			result = KErrNone;
       
   788 			__UHEAP_MARK;
       
   789 			break;
       
   790 		case RSDbgCheckHeap:
       
   791 			result = KErrNone;
       
   792 			__UHEAP_CHECK(aMessage.Int0());
       
   793 			break;
       
   794 		case RSDbgMarkEnd:
       
   795 			result = KErrNone;
       
   796 			__UHEAP_MARKENDC(aMessage.Int0());
       
   797 			break;
       
   798 		case RSDbgFailNext:
       
   799 			result = KErrNone;
       
   800 			if(aMessage.Int0() >= 0)
       
   801 				{
       
   802 				__UHEAP_FAILNEXT(aMessage.Int0());
       
   803 				}
       
   804 			else
       
   805 				{
       
   806 				__UHEAP_RESET;
       
   807 				}
       
   808 			break;
       
   809 #endif		// DEBUG }
       
   810 		default:
       
   811 			result = KErrNotSupported;
       
   812 			break;
       
   813 		}
       
   814 
       
   815     if(completeNow)
       
   816         {
       
   817         aMessage.Complete(result);
       
   818         }
       
   819     }
       
   820 
       
   821 EXPORT_C void CRootServerSession::SuddenDeath(const TInt aError)
       
   822 	/** Handles Sudden Death completion events
       
   823 	 @internalComponent
       
   824 	 */
       
   825     {
       
   826     if(iSuddenDeathListener)
       
   827         {
       
   828         iSuddenDeathMessage.Complete(aError);
       
   829         iSuddenDeathListener = EFalse;
       
   830         }
       
   831     };
       
   832 
       
   833 void CRootServerSession::RegisterHandler(CSessionHandler& aHandler)
       
   834     /** Register session handlers.
       
   835      @internalComponent
       
   836      @param aHandler Reference to handler to be registered to allow deletion
       
   837      */
       
   838 	{
       
   839 	__CFLOG( KLogSubSysRS, KLogCode,_L8("CRootServerSession - Registering handler"));
       
   840 	iActiveHandlers.AddLast(aHandler);
       
   841     }
       
   842 
       
   843 EXPORT_C CRootServerSession::~CRootServerSession()
       
   844 	/** RootserverSession destructor.
       
   845      @internalComponent
       
   846      */
       
   847     {
       
   848 	TDblQueIter<CSessionHandler> handlerIter(iActiveHandlers);
       
   849     CSessionHandler* pHandler;
       
   850 
       
   851     // cancel handlers without completing their RMessages
       
   852     while((pHandler = handlerIter++)!=NULL)
       
   853 		{
       
   854 		if(pHandler->CancelHandler(EFalse, ETrue))
       
   855 			{
       
   856 			delete pHandler;
       
   857 			}
       
   858         }
       
   859     }
       
   860 
       
   861 void CRootServerSession::CloseSession()
       
   862     /** Close session to rootserver.
       
   863      @internalComponent
       
   864      */
       
   865 	{
       
   866 	// cancel all the client's handlers before we die
       
   867     __CFLOG(KLogSubSysRS, KLogCode, _L8("CRootServerSession::CloseSession"));
       
   868 
       
   869 	TDblQueIter<CSessionHandler> handlerIter(iActiveHandlers);
       
   870     CSessionHandler* pHandler;
       
   871 
       
   872     // release any pending messages
       
   873     while((pHandler = handlerIter++)!=NULL)
       
   874 		{
       
   875 		__CFLOG_1(KLogSubSysRS, KLogCode,
       
   876 			_L8("CRootServerSession::CloseSession cancelling handle %X"), pHandler);
       
   877 		if(pHandler->CancelHandler(ETrue, ETrue))
       
   878 			{
       
   879 			delete pHandler;
       
   880 			}
       
   881 		}
       
   882 	}
       
   883 
       
   884 TInt CRootServerSession::Shutdown()
       
   885 	/** Shutdown root server
       
   886 	 If there are any modules running, it creates a new handler
       
   887 	 for each one, which unload their module.  When there are no
       
   888 	 more modules left running, the root server is shutdown
       
   889 	 @internalComponent
       
   890 	 */
       
   891 	{
       
   892 	__CFLOG(KLogSubSysRS, KLogCode, _L8("CRootServerSession::Shutdown"));
       
   893 	return iRootServer->Shutdown();
       
   894 	}
       
   895 
       
   896 TInt CRootServerSession::Forward(const RMessage2& aMessage)
       
   897 	/** Forwards a message to a module
       
   898 	 @internalComponent
       
   899 	 */
       
   900 	{
       
   901 	__CFLOG(KLogSubSysRS, KLogCode, _L8("CRootServerSession::Forward"));
       
   902 	TCFModuleNameF name;
       
   903 	TInt result = aMessage.Read(0, name);
       
   904 	if(result!=KErrNone)
       
   905 		{
       
   906 		return result;
       
   907 		}
       
   908 
       
   909    return iRootServer->Forward(name, aMessage);
       
   910 	}
       
   911 
       
   912 CRootServer* CRootServerSession::RootServer()
       
   913 	{
       
   914 	return iRootServer;
       
   915 	}
       
   916 
       
   917 TInt CRootServerSession::IsCallerConfigurator(const RMessage2& aMessage)
       
   918 	{
       
   919 	return (TInt) iRootServer->IsCallerConfigurator(this, aMessage);
       
   920 	}
       
   921 
       
   922 EXPORT_C void CRootServerSession::Disconnect(const RMessage2& aMessage)
       
   923 	{
       
   924 	iRootServer->DisconnectSession(this);
       
   925 	CSession2::Disconnect(aMessage);
       
   926 	}
       
   927