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