messagingfw/msgtestfw/TestActions/Capabilities/src/SendProxyServer.cpp
changeset 0 8e480a14352b
equal deleted inserted replaced
-1:000000000000 0:8e480a14352b
       
     1 // Copyright (c) 2000-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 // server.cpp
       
    15 // Transient server example - server implementation
       
    16 // 
       
    17 //
       
    18 
       
    19 #include "SendProxyserver.h"
       
    20 #include "MSERVER.H"
       
    21 
       
    22 
       
    23 
       
    24 inline CShutdown::CShutdown()
       
    25 	:CTimer(-1)
       
    26 	{CActiveScheduler::Add(this);}
       
    27 	
       
    28 	
       
    29 inline void CShutdown::ConstructL()
       
    30 	{CTimer::ConstructL();}
       
    31 	
       
    32 	
       
    33 inline void CShutdown::Start()
       
    34 	{After(KSendProxyShutdownDelay);}
       
    35 
       
    36 
       
    37 inline CSendProxyServer::CSendProxyServer()
       
    38 	:CServer2(0,ESharableSessions)
       
    39 	{}
       
    40 
       
    41 
       
    42 
       
    43 EXPORT_C TInt RMessage2Derv::GetiArgs(TInt aPos) const
       
    44 {
       
    45 	return iArgs[aPos];
       
    46 }
       
    47 
       
    48 
       
    49 
       
    50 
       
    51 inline CSendProxyServerSession::CSendProxyServerSession() : iSessionCount(0), iCommand( ENoCommandPending )
       
    52 	{}
       
    53 		
       
    54 	
       
    55 inline CSendProxyServer& CSendProxyServerSession::Server()
       
    56 	{return *static_cast<CSendProxyServer*>(const_cast<CServer2*>(CSession2::Server()));}
       
    57 	
       
    58 	
       
    59 inline TBool CSendProxyServerSession::ReceivePending() const
       
    60 	{return !iReceiveMsg.IsNull();}
       
    61 
       
    62 
       
    63 
       
    64 TInt RMsvServerSessionTest::SendReceive( TInt aFunction,const TIpcArgs& aArgs ) const
       
    65 	{ 
       
    66 	return RMsvServerSession::SendReceive( aFunction,aArgs ); 
       
    67 	}
       
    68 	
       
    69 TInt RMsvServerSessionTest::SendReceive( TInt aFunction ) const
       
    70 	{ 
       
    71 	return RMsvServerSession::SendReceive( aFunction ); 
       
    72 	}
       
    73 	// All we want is to access. Since RSessionBase::SendReceive is protected so is RMsvServerSession::SendReceive
       
    74 	// So as long as we derive from RSessionBase base we should be get access to SendReceive.
       
    75 
       
    76 
       
    77 void RMsvServerSessionTest::SendReceive( TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aRequestStatus ) const
       
    78 	{ 
       
    79 	RMsvServerSession::SendReceive( aFunction,aArgs,aRequestStatus ); 		
       
    80 	}
       
    81 	
       
    82 void RMsvServerSessionTest::SendReceive( TInt aFunction,TRequestStatus& aRequestStatus) const
       
    83 	{ 
       
    84 	return RMsvServerSession::SendReceive( aFunction,aRequestStatus ); 
       
    85 	}
       
    86 
       
    87 
       
    88 void RMsvServerSessionTest::SendReceiveAsync( TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aRequestStatus ) const
       
    89 	{ 
       
    90 	RMsvServerSession::SendReceive( aFunction,aArgs,aRequestStatus ); 		
       
    91 	User::WaitForRequest(aRequestStatus);		
       
    92 		// Lets pretend sync for simplicity sake.
       
    93 	}
       
    94 	
       
    95 void RMsvServerSessionTest::SendReceiveAsync( TInt aFunction,TRequestStatus& aRequestStatus) const
       
    96 	{ 
       
    97 	RMsvServerSession::SendReceive( aFunction,aRequestStatus ); 
       
    98 	User::WaitForRequest(aRequestStatus);
       
    99 		// Lets pretend sync for simplicity sake.
       
   100 	}
       
   101 
       
   102 
       
   103 TInt RMsvServerSessionTest::CreateSession(const TDesC& aServer,const TVersion& aVersion,TInt aAsyncMessageSlots)
       
   104 	{
       
   105 	return RMsvServerSession::CreateSession(aServer, aVersion, aAsyncMessageSlots);
       
   106 	}
       
   107 
       
   108 
       
   109 
       
   110 //
       
   111 
       
   112 
       
   113 TInt StartMsvServer()
       
   114 {
       
   115 
       
   116 	TInt err =  KErrNone ;
       
   117 	// EKA2 is simple No path required 
       
   118 	TBuf<32> serverFile;
       
   119 	
       
   120 	serverFile.Copy(_L("!") );
       
   121 	serverFile.Copy( KMsvServerNameExe );
       
   122 	
       
   123 	_LIT(KExe,".exe");
       
   124 	serverFile.Append(KExe);
       
   125 	RProcess server;
       
   126 	err = server.Create(serverFile,_L(""));
       
   127 	if(err != KErrNone)
       
   128 		return err;
       
   129 		
       
   130 	// Synchronise with the server
       
   131 	TRequestStatus reqStatus;
       
   132 	server.Rendezvous(reqStatus);
       
   133 	server.Resume();
       
   134 	 //Server will call the reciprocal static synchronise call
       
   135 	User::WaitForRequest(reqStatus);
       
   136 	//server.Close();
       
   137 	if(reqStatus.Int() != KErrNone)
       
   138 	{
       
   139 		return reqStatus.Int();
       
   140 	}
       
   141 	
       
   142 	return err;
       
   143 }	
       
   144 
       
   145 
       
   146 void CSendProxyServerSession::CreateL()
       
   147 //
       
   148 // 2nd phase construct for sessions - called by the CServer framework
       
   149 //
       
   150 	{	
       
   151 	
       
   152 	// Start up the messaging server that all messages will be forwarded to. 
       
   153 	TInt error = iMsvServerSession.CreateSession( KMsvServerName, iMsvServerSession.Version(), 2);
       
   154 	if (error==KErrNone)
       
   155 		{ // Session has been started. Server was already running.
       
   156 		}
       
   157 	else
       
   158 		{
       
   159 		error=StartMsvServer();
       
   160 		
       
   161 		if (error!=KErrNone)
       
   162 			{ // Leave
       
   163 			User::LeaveIfError(error);
       
   164 			}
       
   165 		else
       
   166 			{
       
   167 			
       
   168 			TInt error = iMsvServerSession.CreateSession( KMsvServerName, iMsvServerSession.Version(), 2);
       
   169 			if (error!=KErrNone)
       
   170 				{ // Leave					
       
   171 				User::LeaveIfError(error);
       
   172 				}
       
   173 			}
       
   174 		}		
       
   175 
       
   176 	
       
   177 	Server().AddSession();
       
   178 	
       
   179 	}
       
   180 
       
   181 
       
   182 CSendProxyServerSession::~CSendProxyServerSession()
       
   183 	{	
       
   184 	iMsvServerSession.Close();
       
   185 	Server().DropSession();		
       
   186 	}
       
   187 
       
   188 
       
   189 
       
   190 void CSendProxyServerSession::ServiceL(const RMessage2& aMessage)
       
   191 //
       
   192 // Handle a client request.
       
   193 // Leaving is handled by CSendProxyServer::ServiceError() which reports
       
   194 // the error code to the client
       
   195 //
       
   196 	{
       
   197 	TInt messageFunction = aMessage.Function();
       
   198 	
       
   199 	if (messageFunction==ESendData)
       
   200 		{	// We are setting up buffers as next time we actually execute the command.
       
   201 			// _ASSERT( iCommand == ENoCommandPending );
       
   202 			// Make sure we do not have another command pending.
       
   203 		iCommand = (TSendProxyMessages) aMessage.Int0();  //???? fix casts  
       
   204 		iFlags = aMessage.Int1();
       
   205 		aMessage.Complete( KErrNone );		
       
   206 		}
       
   207 	else if (messageFunction==EGetServerSecureId)
       
   208 		{ // This must done for the proxy server. 
       
   209 		  // We are not passing the data on to the messaging server
       
   210 
       
   211 		TSecureId cServerSecureId;
       
   212 		TPckg<TSecureId> buf(cServerSecureId);
       
   213 		
       
   214 		aMessage.ReadL(0,buf);
       
   215 			
       
   216 		cServerSecureId = RProcess().SecureId();
       
   217 		aMessage.WriteL(0,buf); 
       
   218 								
       
   219 		aMessage.Complete( KErrNone );
       
   220 		}
       
   221 	else if (messageFunction==EGetServerCapabilities)
       
   222 		{ // return the capabilities for the proxy server. 
       
   223 		  // We are not passing the data on to the messaging server
       
   224 
       
   225 		TInt32 cServerCaps;
       
   226 		TPckg<TInt32> buf(cServerCaps);
       
   227 		
       
   228 		aMessage.ReadL(0,buf);
       
   229 		
       
   230 		ReadCapabilities(cServerCaps);
       
   231 
       
   232 		aMessage.WriteL(0,buf); 
       
   233 								
       
   234 		aMessage.Complete( KErrNone );
       
   235 		}
       
   236 	else if ( messageFunction==EReceive )
       
   237 		{ 
       
   238 		if (ReceivePending())
       
   239 			PanicClient(aMessage,EPanicAlreadyReceiving);
       
   240 		else
       
   241 			{
       
   242 			iReceiveMsg=aMessage;
       
   243 			iReceiveLen=aMessage.Int1();
       
   244 			}
       
   245 		}
       
   246 	else if ( messageFunction==ECancelReceive )
       
   247 		{				
       
   248 		if (ReceivePending())
       
   249 			iReceiveMsg.Complete(KErrCancel);
       
   250 		aMessage.Complete( KErrNone );
       
   251 		}
       
   252 	else
       
   253 		{  // We are expected to execute a command.
       
   254 		TInt complete = DoCommandL( (const RMessage2Derv&) aMessage );		
       
   255 
       
   256 		// Indicate that we succesfully executed a full command and can take another.			
       
   257 		iCommand = ENoCommandPending;
       
   258 		iFlags = 0;
       
   259 		aMessage.Complete( complete );
       
   260 		}	
       
   261 		
       
   262 	}
       
   263 
       
   264 
       
   265 void CSendProxyServerSession::ReadCapabilities(TInt32& aServerCaps)
       
   266 	{
       
   267 	aServerCaps=0;
       
   268 
       
   269 	if (RProcess().HasCapability(ECapabilityTCB))
       
   270 		aServerCaps |= (1<<ECapabilityTCB);
       
   271 	
       
   272 	if (RProcess().HasCapability(ECapabilityCommDD))
       
   273 		aServerCaps |= (1<<ECapabilityCommDD);
       
   274 	
       
   275 	if (RProcess().HasCapability(ECapabilityPowerMgmt))
       
   276 		aServerCaps |= (1<<ECapabilityPowerMgmt);
       
   277 	
       
   278 	if (RProcess().HasCapability(ECapabilityMultimediaDD))
       
   279 		aServerCaps |= (1<<ECapabilityMultimediaDD);
       
   280 
       
   281 	if (RProcess().HasCapability(ECapabilityReadDeviceData))
       
   282 		aServerCaps |= (1<<ECapabilityReadDeviceData);
       
   283 	
       
   284 	if (RProcess().HasCapability(ECapabilityWriteDeviceData))
       
   285 		aServerCaps |= (1<<ECapabilityWriteDeviceData);
       
   286 
       
   287 	if (RProcess().HasCapability(ECapabilityDRM))
       
   288 		aServerCaps |= (1<<ECapabilityDRM);
       
   289 	
       
   290 	if (RProcess().HasCapability(ECapabilityTrustedUI))
       
   291 		aServerCaps |= (1<<ECapabilityTrustedUI);
       
   292 
       
   293 	if (RProcess().HasCapability(ECapabilityProtServ))
       
   294 		aServerCaps |= (1<<ECapabilityProtServ);
       
   295 
       
   296 	if (RProcess().HasCapability(ECapabilityDiskAdmin))
       
   297 		aServerCaps |= (1<<ECapabilityDiskAdmin);
       
   298 
       
   299 	if (RProcess().HasCapability(ECapabilityNetworkControl))
       
   300 		aServerCaps |= (1<<ECapabilityNetworkControl);
       
   301 
       
   302 	if (RProcess().HasCapability(ECapabilityAllFiles))
       
   303 		aServerCaps |= (1<<ECapabilityAllFiles);
       
   304 
       
   305 	if (RProcess().HasCapability(ECapabilitySwEvent))
       
   306 		aServerCaps |= (1<<ECapabilitySwEvent);
       
   307 
       
   308 	if (RProcess().HasCapability(ECapabilityNetworkServices))
       
   309 		aServerCaps |= (1<<ECapabilityNetworkServices);
       
   310 
       
   311 	if (RProcess().HasCapability(ECapabilityLocalServices))
       
   312 		aServerCaps |= (1<<ECapabilityLocalServices);
       
   313 
       
   314 	if (RProcess().HasCapability(ECapabilityReadUserData))
       
   315 		aServerCaps |= (1<<ECapabilityReadUserData);
       
   316 
       
   317 	if (RProcess().HasCapability(ECapabilityWriteUserData))
       
   318 		aServerCaps |= (1<<ECapabilityWriteUserData);
       
   319 
       
   320 	if (RProcess().HasCapability(ECapabilityLocation))
       
   321 		aServerCaps |= (1<<ECapabilityLocation);
       
   322 
       
   323 	if (RProcess().HasCapability(ECapabilitySurroundingsDD))
       
   324 		aServerCaps |= (1<<ECapabilitySurroundingsDD);
       
   325 
       
   326 	if (RProcess().HasCapability(ECapabilityUserEnvironment))
       
   327 		aServerCaps |= (1<<ECapabilityUserEnvironment);
       
   328 
       
   329 		
       
   330 	}
       
   331 
       
   332 
       
   333 //*************
       
   334 
       
   335 
       
   336 void CSendProxyServerSession::SetupTIpcArgL(const RMessage2Derv& aMessage, TInt aPos, TIpcArgs& atipcArgs )
       
   337 	{		
       
   338 	const TInt mask = ( 1<<TIpcArgs::KBitsPerType )-1;
       
   339 	
       
   340 	const TInt bits_shift  = (aPos * TIpcArgs::KBitsPerType );
       
   341 	const TInt type_flags = ( iFlags >> bits_shift ) & mask ;
       
   342 	
       
   343 		
       
   344 	if ( type_flags == TIpcArgs::EUnspecified )
       
   345 		{ // Unspecified so must be TInt.		
       
   346 		TInt tmp = aMessage.GetiArgs(aPos);
       
   347 		atipcArgs.Set( aPos, (TAny*) tmp);
       
   348 		}
       
   349 	else if ( type_flags  == TIpcArgs::EDesC8 )
       
   350 		{ // We have a read only descriptor can not use GetDesMaxLength on it. 
       
   351 		
       
   352 		TInt maxLength1 = aMessage.GetDesLength(aPos);
       
   353 		HBufC8* buffer1 = HBufC8::NewL(maxLength1);
       
   354 		iBuffer8[aPos].Assign(buffer1);
       
   355 			// Owns the buffer.
       
   356 
       
   357 		TPtr8 ptrBuffer1= (buffer1->Des());						
       
   358 		
       
   359 		aMessage.ReadL( aPos, ptrBuffer1 );		
       
   360 		atipcArgs.Set( aPos, buffer1);
       
   361 			// buffer is considered constant so internal flags in atipcArgs will be okay.
       
   362 		}
       
   363 	else if ( type_flags == TIpcArgs::EDes8 )
       
   364 		{ // Just generate a descriptor and copy the contents into it.
       
   365 		  // We need GetDesMaxLength because it is read/write and somebody will right more than the current length.
       
   366 
       
   367 		TInt maxLength2 = aMessage.GetDesMaxLength(aPos);		
       
   368 		 
       
   369 		HBufC8* buffer2 = HBufC8::NewL(maxLength2);
       
   370 		iBuffer8[aPos].Assign(buffer2);
       
   371 			// we want the buffer to read/write which is why we use RBuf8.
       
   372 			// The RBuf8 takes ownership of the HBuf.
       
   373 		
       
   374 		iTPtr8[aPos] = new (ELeave) TPtr8(buffer2->Des());
       
   375 								
       
   376 		aMessage.ReadL( aPos, *(iTPtr8[aPos]) );			
       
   377 		atipcArgs.Set( aPos, iTPtr8[aPos] );		
       
   378 			
       
   379 		}
       
   380 	else if (  type_flags == TIpcArgs::EDesC16 )
       
   381 		{ // We have a read only descriptor can not use GetDesMaxLength on it. 
       
   382 		
       
   383 		TInt maxLength3 = aMessage.GetDesLength(aPos);
       
   384 		HBufC16* buffer3 = HBufC16::NewL(maxLength3);
       
   385 		iBuffer16[aPos].Assign(buffer3);
       
   386 			// Owns the buffer.
       
   387 
       
   388 		TPtr16 ptrBuffer3= (buffer3->Des());						
       
   389 		
       
   390 		aMessage.ReadL( aPos, ptrBuffer3 );		
       
   391 		atipcArgs.Set( aPos, buffer3);
       
   392 			// buffer is considered constant so internal flags in atipcArgs will be okay.
       
   393 		}
       
   394 	else if ( type_flags == TIpcArgs::EDes16 )
       
   395 		{ // Just generate a descriptor and copy the contents into it.
       
   396 		  // We need GetDesMaxLength because it is read/write and somebody will right more than the current length.
       
   397 
       
   398 		TInt maxLength4 = aMessage.GetDesMaxLength(aPos);		
       
   399 		 
       
   400 		HBufC16* buffer4 = HBufC16::NewL(maxLength4);
       
   401 		iBuffer16[aPos].Assign(buffer4);
       
   402 			// we want the buffer to read/write which is why we use RBuf16.
       
   403 			// The RBuf16 takes ownership of the HBuf.
       
   404 		
       
   405 		iTPtr16[aPos] = new (ELeave) TPtr16(buffer4->Des());
       
   406 								
       
   407 		aMessage.ReadL( aPos, *(iTPtr16[aPos]) );			
       
   408 		atipcArgs.Set( aPos, iTPtr16[aPos] );		
       
   409 			
       
   410 		}
       
   411 	else if ( type_flags == TIpcArgs::EHandle )
       
   412 		{		
       
   413 		TInt tmp = aMessage.GetiArgs(aPos);
       
   414 		atipcArgs.Set( aPos, tmp);
       
   415 		}		
       
   416 	else
       
   417 		{ // Unknown error.
       
   418 		User::LeaveIfError(KErrGeneral);
       
   419 		}
       
   420 	
       
   421 	}
       
   422 
       
   423 void CSendProxyServerSession::SetupTIpcArgsL(const RMessage2Derv& aMessage, TIpcArgs& atipcArgs)
       
   424 	{	
       
   425 	SetupTIpcArgL( aMessage, 0, atipcArgs );
       
   426 	SetupTIpcArgL( aMessage, 1, atipcArgs );		
       
   427 	SetupTIpcArgL( aMessage, 2, atipcArgs );		
       
   428 	SetupTIpcArgL( aMessage, 3, atipcArgs );			
       
   429 	}
       
   430 
       
   431 
       
   432 //*************
       
   433 
       
   434 void CSendProxyServerSession::SetupReturnTIpcArgL(const RMessage2Derv& aMessage, TInt aPos )
       
   435 	{		
       
   436 	const TInt mask = ( 1<<TIpcArgs::KBitsPerType )-1;
       
   437 	
       
   438 	const TInt bits_shift  = (aPos * TIpcArgs::KBitsPerType );
       
   439 	const TInt type_flags = ( iFlags >> bits_shift ) & mask ;
       
   440 		
       
   441 	if (type_flags == TIpcArgs::EUnspecified)
       
   442 		{ // Do nothing can not write back to the args of a message.
       
   443 		}
       
   444 	else if ( type_flags == TIpcArgs::EDesC8 )
       
   445 		{ // We have constant descriptor no action required as we can not change it.
       
   446 		}
       
   447 	else if ( type_flags == TIpcArgs::EDes8 )
       
   448 		{ // We have a read/write descriptor we need to copy back any changes.
       
   449 		aMessage.WriteL( aPos, *(iTPtr8[aPos]) );		
       
   450 		}
       
   451 	else if ( type_flags == TIpcArgs::EDesC16 )
       
   452 		{ // We have constant descriptor no action required as we can not change it.
       
   453 		}
       
   454 	else if ( type_flags  == TIpcArgs::EDes16 )
       
   455 		{ // We have a read/write descriptor we need to copy back any changes.
       
   456 		aMessage.WriteL( aPos, *(iTPtr16[aPos]) );		
       
   457 		}
       
   458 	else if ( type_flags == TIpcArgs::EHandle )
       
   459 		{ //Do nothing as handles should not change.
       
   460 		}
       
   461 	else
       
   462 		{ // may need to implement 16 bit descriptors etc.
       
   463 		User::LeaveIfError(KErrGeneral);
       
   464 		}
       
   465 	
       
   466 	}
       
   467 
       
   468 
       
   469 void CSendProxyServerSession::SetupReturnTIpcArgsL(const RMessage2Derv& aMessage)
       
   470 	{	
       
   471 	SetupReturnTIpcArgL( aMessage, 0 );
       
   472 	SetupReturnTIpcArgL( aMessage, 1 );		
       
   473 	SetupReturnTIpcArgL( aMessage, 2 );		
       
   474 	SetupReturnTIpcArgL( aMessage, 3 );			
       
   475 	}
       
   476 
       
   477 
       
   478 void CSendProxyServerSession::ClearBuffer(TInt aPos)
       
   479 	{
       
   480 	
       
   481 	iBuffer8[aPos].Close();
       
   482 	delete iTPtr8[aPos];
       
   483 	iTPtr8[aPos]=0;
       
   484 
       
   485 	iBuffer16[aPos].Close();
       
   486 	delete iTPtr16[aPos];
       
   487 	iTPtr16[aPos]=0;
       
   488 		
       
   489 	}
       
   490 
       
   491 
       
   492 
       
   493 void CSendProxyServerSession::ClearBuffers()
       
   494 	{	
       
   495 	
       
   496 	ClearBuffer( 0 );
       
   497 	ClearBuffer( 1 );		
       
   498 	ClearBuffer( 2 );		
       
   499 	ClearBuffer( 3 );		
       
   500 	
       
   501 	}
       
   502 
       
   503 
       
   504 TInt CSendProxyServerSession::DoCommandL(const RMessage2Derv& aMessage ) 
       
   505 	{
       
   506 	TInt complete=KErrNone;	
       
   507 			
       
   508 	switch (iCommand)
       
   509 		{
       
   510 		
       
   511 		case ESend:
       
   512 			{		
       
   513 			
       
   514 			TIpcArgs tipcArgs;
       
   515 			SetupTIpcArgsL( ( (const RMessage2Derv&) aMessage ), tipcArgs);			
       
   516 			complete = iMsvServerSession.SendReceive( aMessage.Function(), tipcArgs );			
       
   517 			SetupReturnTIpcArgsL( (const RMessage2Derv&) aMessage);
       
   518 			ClearBuffers();
       
   519 			break;
       
   520 			}
       
   521 						
       
   522 		case ESendAsyncWait:
       
   523 			{				
       
   524 
       
   525 			TIpcArgs tipcArgs1;
       
   526 			SetupTIpcArgsL( ( (const RMessage2Derv&) aMessage ), tipcArgs1);			
       
   527 			
       
   528 			TRequestStatus requestStatus=KRequestPending;
       
   529 			iMsvServerSession.SendReceive( aMessage.Function(), tipcArgs1 , requestStatus );
       
   530 			User::WaitForRequest(requestStatus);			
       
   531 			SetupReturnTIpcArgsL( (const RMessage2Derv&) aMessage);
       
   532 			ClearBuffers();
       
   533 			complete = requestStatus.Int();
       
   534 
       
   535 			break;
       
   536 			}
       
   537 		default:
       
   538 			{
       
   539 			complete=KErrGeneral;
       
   540 			PanicClient(aMessage,EPanicIllegalFunction);			
       
   541 			break;
       
   542 			}
       
   543 		}
       
   544 				
       
   545 	return complete;			
       
   546 	}
       
   547 
       
   548 void CSendProxyServerSession::ServiceError(const RMessage2& aMessage,TInt aError)
       
   549 //
       
   550 // Handle an error from CSendProxyServerSession::ServiceL()
       
   551 // A bad descriptor error implies a badly programmed client, so panic it;
       
   552 // otherwise use the default handling (report the error to the client)
       
   553 //
       
   554 	{
       
   555 	if (aError==KErrBadDescriptor)
       
   556 		PanicClient(aMessage,EPanicBadDescriptor);
       
   557 	CSession2::ServiceError(aMessage,aError);
       
   558 	}
       
   559 
       
   560 void CShutdown::RunL()
       
   561 //
       
   562 // Initiate server exit when the timer expires
       
   563 //
       
   564 	{
       
   565 	CActiveScheduler::Stop();
       
   566 	}
       
   567 
       
   568 CServer2* CSendProxyServer::NewLC()
       
   569 	{
       
   570 	CSendProxyServer* self=new(ELeave) CSendProxyServer;
       
   571 	CleanupStack::PushL(self);
       
   572 	self->ConstructL();
       
   573 	return self;
       
   574 	}
       
   575 
       
   576 
       
   577 //**********************************
       
   578 
       
   579 void CSendProxyServer::ConstructL()
       
   580 //
       
   581 // 2nd phase construction - ensure the timer and server objects are running
       
   582 //
       
   583 	{
       
   584 	StartL(KSendProxyServerName);
       
   585 			
       
   586 	iShutdown.ConstructL();
       
   587 		// ensure that the server still exits even if the 1st client fails to connect
       
   588 	iShutdown.Start();	
       
   589 	}
       
   590 
       
   591 
       
   592 CSession2* CSendProxyServer::NewSessionL(const TVersion&,const RMessage2&) const
       
   593 //
       
   594 // Cretae a new client session. This should really check the version number.
       
   595 //
       
   596 	{
       
   597 	return new(ELeave) CSendProxyServerSession();
       
   598 	}
       
   599 
       
   600 void CSendProxyServer::AddSession()
       
   601 //
       
   602 // A new session is being created
       
   603 // Cancel the shutdown timer if it was running
       
   604 //
       
   605 	{
       
   606 	++iSessionCount;
       
   607 	iShutdown.Cancel();
       
   608 	}
       
   609 
       
   610 void CSendProxyServer::DropSession()
       
   611 //
       
   612 // A session is being destroyed
       
   613 // Start the shutdown timer if it is the last session.
       
   614 //
       
   615 	{
       
   616 	if (--iSessionCount==0)
       
   617 		iShutdown.Start();
       
   618 	}
       
   619 
       
   620 
       
   621 
       
   622 void PanicClient(const RMessagePtr2& aMessage,TSendProxyServerPanic aPanic)
       
   623 //
       
   624 // RMessagePtr2::Panic() also completes the message. This is:
       
   625 // (a) important for efficient cleanup within the kernel
       
   626 // (b) a problem if the message is completed a second time
       
   627 //
       
   628 	{
       
   629 	_LIT(KPanic,"SendProxyServer");
       
   630 	aMessage.Panic(KPanic,aPanic);
       
   631 	}
       
   632 
       
   633 
       
   634 //******************************
       
   635 
       
   636 
       
   637 static void RunServerL()
       
   638 //
       
   639 // Perform all server initialisation, in particular creation of the
       
   640 // scheduler and server and then run the scheduler
       
   641 //
       
   642 	{
       
   643 		
       
   644 	// naming the server thread after the server helps to debug panics
       
   645 	User::LeaveIfError(User::RenameThread(KSendProxyServerName));
       
   646 	//
       
   647 	// create and install the active scheduler we need
       
   648 	CActiveScheduler* s=new(ELeave) CActiveScheduler;
       
   649 	CleanupStack::PushL(s);
       
   650 	CActiveScheduler::Install(s);
       
   651 	//
       
   652 	// create the server (leave it on the cleanup stack)
       
   653 	CSendProxyServer::NewLC();
       
   654 	//
       
   655 	// Initialisation complete, now signal the client
       
   656 #ifdef __SENDPROXYSERVER_NO_PROCESSES__
       
   657 	RThread::Rendezvous(KErrNone);
       
   658 #else
       
   659 	RProcess::Rendezvous(KErrNone);
       
   660 #endif
       
   661 	//
       
   662 	// Ready to run
       
   663 	CActiveScheduler::Start();
       
   664 	//
       
   665 	// Cleanup the server and scheduler
       
   666 	CleanupStack::PopAndDestroy(2);
       
   667 
       
   668 	}
       
   669 
       
   670 
       
   671 
       
   672 //****************************************
       
   673 
       
   674 
       
   675 TInt E32Main()
       
   676 //
       
   677 // Server process entry-point
       
   678 //
       
   679 	{
       
   680 	__UHEAP_MARK;
       
   681 	//
       
   682 	CTrapCleanup* cleanup=CTrapCleanup::New();
       
   683 	TInt r=KErrNoMemory;
       
   684 	if (cleanup)
       
   685 		{
       
   686 		TRAP(r,RunServerL());
       
   687 		delete cleanup;
       
   688 		}
       
   689 	//
       
   690 	__UHEAP_MARKEND;
       
   691 	return r;
       
   692 	}
       
   693 
       
   694 #ifdef __SENDPROXYSERVER_NO_PROCESSES__
       
   695 
       
   696 // The server binary is an "EPOCEXE" target type
       
   697 // Thus the server parameter passing and startup code for WINS and EPOC are
       
   698 // significantly different.
       
   699 //
       
   700 // In EKA1 WINS, the EPOCEXE target is a DLL with an entry point called WinsMain,
       
   701 // taking no parameters and returning TInt. This is not really valid as a thread
       
   702 // function which takes a TAny* parameter which we need.
       
   703 //
       
   704 // So the DLL entry-point WinsMain() is used to return a TInt representing the
       
   705 // real thread function within the DLL. This is good as long as
       
   706 // sizeof(TInt)>=sizeof(TThreadFunction).
       
   707 //
       
   708 
       
   709 static TInt ThreadFunction(TAny*)
       
   710 //
       
   711 // WINS thread entry-point function.
       
   712 //
       
   713 	{
       
   714 	return E32Main();
       
   715 	}
       
   716 
       
   717 IMPORT_C TInt WinsMain();
       
   718 EXPORT_C TInt WinsMain()
       
   719 //
       
   720 // WINS DLL entry-point. Just return the real thread function 
       
   721 // cast to TInt
       
   722 //
       
   723 	{
       
   724 	return reinterpret_cast<TInt>(&ThreadFunction);
       
   725 	}
       
   726 
       
   727 TInt E32Dll(TDllReason)
       
   728 	{
       
   729 	return KErrNone;
       
   730 	}
       
   731 
       
   732 #endif