os/security/cryptomgmtlibs/securitycommonutils/source/scsclient/scsclientbase.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 * Generic client-side code for client-server interaction.
    16 * Attempts to establish a connection to a session counting server,
    17 * starting the process if required.
    18 *
    19 */
    20 
    21 
    22 /**
    23  @file
    24 */
    25 
    26 #include <scs/scsclient.h>
    27 
    28 #include <scs/scscommon.h>
    29 
    30 using namespace ScsImpl;
    31 
    32 
    33 EXPORT_C RScsClientBase::RScsClientBase()
    34 /**
    35 	This constructor is protected to ensure this class is not
    36 	instantiated directly.
    37  */
    38 :	RSessionBase()
    39 	{
    40 	// empty.
    41 	}
    42 
    43 EXPORT_C void RScsClientBase::Close()
    44 /**
    45 	This method should be used in preference to RScsSessionBase::Close
    46 	because it sends a message to cancel any outstanding requests on the
    47 	session or its subsessions.
    48  */
    49 	{
    50 	if(iHandle)
    51 		{
    52 		RSessionBase::SendReceive(EPreCloseSession);
    53 		RSessionBase::Close();
    54 		}
    55 	}
    56 
    57 TInt RScsClientBase::StartServerProcess(const TDesC& aExeName, const TUidType& aFullExeUid)
    58 /**
    59 	This function is defined for the convenience of subclasses which need to start
    60 	a server process before they can connect to the server.
    61 
    62 	@param	aExeName		Executable which hosts the server.
    63 	@param	aFullExeUid		The server executable's full UID.  This is used to ensure the
    64 							intended executable is started, and not another executable
    65 							with the same name.
    66 	@return					Symbian OS error code.  KErrNone indicates success, and any other
    67 							value indicates failure.
    68 	@pre This function should only be called by Connect(const TVersion&) if the server is
    69 		not already running.
    70  */
    71 	{
    72 	RProcess pr;
    73 	TInt r = pr.Create(aExeName, /* aCommand */ KNullDesC, aFullExeUid);
    74 	if (r != KErrNone)
    75 		return r;
    76 
    77 	TRequestStatus rs;
    78 	pr.Rendezvous(rs);
    79 	if (rs != KRequestPending)
    80 		r = rs.Int();
    81 	else
    82 		{
    83 		pr.Resume();
    84 		User::WaitForRequest(rs);
    85 		if (rs.Int()==KErrAlreadyExists)
    86 			r=KErrAlreadyExists;
    87 		else
    88 			r = (pr.ExitType() == EExitPending) ? rs.Int() : KErrGeneral;
    89 		}
    90 
    91 	pr.Close();
    92 	return r;
    93 	}
    94 
    95 EXPORT_C TInt RScsClientBase::Connect(
    96 	const TDesC& aSvrName, const TVersion& aReqVer, const TDesC& aExeName, const TUidType& aFullExeUid)
    97 /**
    98 	Attempt to connect to the named server.  If the server is not available then attempt
    99 	to start its hosting process.
   100 
   101 	@param	aSvrName		Name of server to connect to.
   102 	@param	aReqVer			Required server version.
   103 	@param	aExeName		Executable which hosts the server.  This function will launch this
   104 							executable if the server is not running.
   105 	@param	aFullExeUid		The server executable's full UID.  This ensures the intended
   106 							executable is started, and not another executable with the same name.
   107 	@return					Symbian OS error code.  KErrNone indicates success,
   108 							and any other value indicates failure.
   109  */
   110 	{
   111 	TInt retries = 2;		// number of remaining retries
   112 
   113 	for (;;)
   114 		{
   115 		TInt r = CreateSession(aSvrName, aReqVer);
   116 		
   117 		// if connected then finished
   118 		if (r == KErrNone)
   119 			return r;
   120 
   121 		// if any reason other than server not available then abort
   122 		if (r != KErrNotFound && r != KErrServerTerminated)
   123 			return r;
   124 
   125 		if (--retries == 0)
   126 			return r;
   127 
   128 		r = StartServerProcess(aExeName, aFullExeUid);
   129 		if (r != KErrNone && r != KErrAlreadyExists)
   130 			return r;
   131 		}	// for (;;)
   132 	}
   133 
   134 // -------- server heap checking --------
   135 
   136 EXPORT_C TInt RScsClientBase::SetServerHeapFail(TInt aRate)
   137 /**
   138 	Start marking the server heap and set a deterministic
   139 	fail rate.  This should matched with a call to EndServerHeapFail.
   140 	
   141 	This function is empty in release builds.
   142 	
   143 	@param	aRate			Number of allocations after which allocation
   144 							should fail on the server heap.
   145 	@see EndServerHeapFail
   146 	@see __UHEAP_MARK
   147 	@see __UHEAP_SETFAIL
   148  */
   149 	{
   150 #ifndef _DEBUG
   151 	(void) aRate;
   152 	return KErrNone;
   153 #else
   154 	TIpcArgs ipc(aRate);
   155 	return RSessionBase::SendReceive(ScsImpl::EUHeapSetFail, ipc);
   156 #endif
   157 	}
   158 
   159 EXPORT_C TInt RScsClientBase::ResetServerHeapFail()
   160 /**
   161 	Finish marking the server heap and reset the failure rate.
   162 	This should match a previous call to SetServerHeapFail.
   163 
   164 	If there is a heap imbalance, then the server will be panicked.
   165 
   166 	This function is empty in release builds.
   167 	
   168 	@see SetServerHeapFail
   169 	@see __UHEAP_MARKEND
   170 	@see __UHEAP_RESET
   171  */
   172 	{
   173 #ifdef _DEBUG
   174 	return RSessionBase::SendReceive(ScsImpl::EUHeapResetFail);	
   175 #else
   176 	return KErrNone;
   177 #endif
   178 	}
   179 
   180 // -------- passing arguments to a server-side session --------
   181 
   182 EXPORT_C TInt RScsClientBase::ShutdownServer()
   183 /**
   184 DEBUG USE ONLY - Tells the server to shutdown down ASAP, and block
   185 until it has done so. This also closes the current session.
   186 
   187 If the server is not configured to use a inactivity shutdown timer,
   188 this will fail with KErrNotSupported.
   189 
   190 nb. You may still need to call the Close function of a derived class
   191 to ensure it gets to cleanup...
   192 
   193 	@return					Symbian OS error code where KErrNone indicates
   194 							success and any other value indicates failure.
   195  */
   196 	{
   197 	// Find servers PID
   198 	TPckgBuf<TProcessId> idBuf;
   199 	TIpcArgs args(&idBuf);
   200 	TInt r = RSessionBase::SendReceive(ScsImpl::EGetServerPid, args);
   201 	if(r != KErrNone) return r;
   202 
   203 	// Open a handle for the server thread
   204 	RProcess server;
   205 	r = server.Open(idBuf(), EOwnerThread);
   206 	if(r != KErrNone) return r;
   207 	
   208 	// Logon to the server process to spot when it exits
   209 	TRequestStatus rs;
   210 	server.Logon(rs);
   211 
   212 	// Ask the server to exit ASAP
   213 	r = RSessionBase::SendReceive(ScsImpl::EShutdownAsap);
   214 	if(r != KErrNone)
   215 		{
   216 		(void) server.LogonCancel(rs);
   217 		server.Close();
   218 		return r;
   219 		}
   220 
   221 	// Close our session
   222 	Close();
   223 
   224 	// Wait for the server to finish shutting down
   225 	User::WaitForRequest(rs); // nb. we do not care what code it shutdown with.
   226 
   227 	// Close our server process handle
   228 	server.Close();
   229 
   230 	return KErrNone;
   231 	}
   232 
   233 // -------- passing arguments to a server-side session --------
   234 
   235 EXPORT_C TInt RScsClientBase::CallSessionFunction(TInt aFunction) const
   236 /**
   237 	Send a command to the corresponding server-side session.  The
   238 	subclass uses this function instead of directly calling
   239 	RSubSessionBase::SendReceive because it adds the SCS code
   240 	which marks this as an ordinary session call.
   241 	
   242 	@param	aFunction		Function identifier.  Bits 31:24 must be zero,
   243 							because they are reserved for SCS commands.
   244 	@return					Error code with which the server completed the request.
   245  */
   246 	{
   247 	__ASSERT_DEBUG(! ScsFieldUsed(aFunction), ClientSidePanic(EScsClNoArgsSessUsedScs));
   248 	
   249 	TInt f = ECallSessionFunc | aFunction;
   250 	return RSessionBase::SendReceive(f);
   251 	}
   252 
   253 EXPORT_C TInt RScsClientBase::CallSessionFunction(TInt aFunction, const TIpcArgs& aArgs) const
   254 /**
   255 	Send a command to the corresponding server-side session.  The
   256 	subclass uses this function instead of directly calling
   257 	RSubSessionBase::SendReceive because it adds the SCS code which
   258 	marks this as an ordinary session call.
   259 
   260 	@param	aFunction		Session function identifier.  Bits 31:24 must be zero,
   261 							because they are reserved for SCS commands.
   262 	@param	aArgs			Standard IPC arguments.
   263 	@return					Error code with which the server completed the request.
   264  */
   265 	{
   266 	__ASSERT_DEBUG(! ScsFieldUsed(aFunction), ClientSidePanic(EScsClArgsSessUsedScs));
   267 	
   268 	TInt f = ECallSessionFunc | aFunction;
   269 	return RSessionBase::SendReceive(f, aArgs);
   270 	}
   271 
   272 EXPORT_C void RScsClientBase::CallSessionFunction(TInt aFunction, const TIpcArgs& aArgs, TRequestStatus& aStatus) const
   273 /**
   274 	Send the supplied function identifier and arguments to the server-side
   275 	session.  The subclass uses this function instead of directly calling
   276 	RSubSessionBase::SendReceive because it adds the SCS code which marks
   277 	this as an ordinary session call.
   278 
   279 	@param	aFunction		Session function identifier.  Bits 31:24 must be zero,
   280 							because they are reserved for SCS commands.
   281 	@param	aArgs			Standard IPC arguments.
   282 	@param	aStatus			This will be completed by the server when it has
   283 							finished handling the function.
   284  */
   285 	{
   286 	__ASSERT_DEBUG(! ScsFieldUsed(aFunction), ClientSidePanic(EScsClArgsSessAsyncUsedScs));
   287 	
   288 	TInt f = ECallSessionFunc | aFunction;
   289 	RSessionBase::SendReceive(f, aArgs, aStatus);
   290 	}
   291 
   292 EXPORT_C void RScsClientBase::CancelSessionFunction(TInt aFunction) const
   293 /**
   294 	Cancel an outstanding session request.  This has no effect if the
   295 	request is not outstanding.
   296 	
   297 	@param	aFunction		Implementation function.  This must be the
   298 							same value that was supplied to CallSessionFunction.
   299  */
   300 	{
   301 	__ASSERT_DEBUG(! ScsFieldUsed(aFunction), ClientSidePanic(EScsClCancelSessUsedScs));
   302 	
   303 	TInt f = ECancelSessionFunc | aFunction;
   304 	RSessionBase::SendReceive(f);
   305 	}
   306