os/ossrv/lowlevellibsandfws/apputils/src/Baksrv.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/lowlevellibsandfws/apputils/src/Baksrv.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1453 @@
     1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include <baksrv.h>
    1.20 +#include "Baksrvs.h"
    1.21 +#include <babackup.h>
    1.22 +#include <bafl/backup_std.h>
    1.23 +#include <basched.h>
    1.24 +#include <bsul/clientmessage.h>
    1.25 +#include "patchdata.h"
    1.26 +
    1.27 +extern const BSUL::TClientMessageServerData KServerData;
    1.28 +
    1.29 +const TInt KBakServMaxOperationTimerLoops = 3; // Number of iterations for base operation timer
    1.30 +
    1.31 +_LIT(KPanic,"BackupServer");
    1.32 +//
    1.33 +// RMessage::Panic() also completes the message. This is:
    1.34 +// (a) important for efficient cleanup within the kernel
    1.35 +// (b) a problem if the message is completed a second time
    1.36 +//
    1.37 +void PanicClient(const RMessagePtr2& aMessage, TInt aPanic)
    1.38 +	{
    1.39 +	aMessage.Panic(KPanic,aPanic);
    1.40 +	}
    1.41 +
    1.42 +
    1.43 +//
    1.44 +// class CShutdownServer
    1.45 +//
    1.46 +
    1.47 +NONSHARABLE_CLASS(CShutdownServer) : public CTimer
    1.48 +	{
    1.49 +	enum {KMyShutdownDelay=0x2000000};	// approx 2s
    1.50 +public:
    1.51 +	inline CShutdownServer();
    1.52 +	inline void ConstructL();
    1.53 +	inline void Start();
    1.54 +private:
    1.55 +	void RunL();
    1.56 +	};
    1.57 +
    1.58 +inline CShutdownServer::CShutdownServer()
    1.59 +	:CTimer(-1)
    1.60 +	{
    1.61 +	CActiveScheduler::Add(this);
    1.62 +	}
    1.63 +
    1.64 +inline void CShutdownServer::ConstructL()
    1.65 +	{
    1.66 +	CTimer::ConstructL();
    1.67 +	}
    1.68 +inline void CShutdownServer::Start()
    1.69 +	{
    1.70 +	After(KMyShutdownDelay);
    1.71 +	}
    1.72 +
    1.73 +//
    1.74 +// Initiate server exit when the timer expires
    1.75 +//
    1.76 +void CShutdownServer::RunL()
    1.77 +	{
    1.78 +	CActiveScheduler::Stop();
    1.79 +	}
    1.80 +
    1.81 +
    1.82 +//
    1.83 +// class CBaServBackupScheduler
    1.84 +//
    1.85 +
    1.86 +EXPORT_C CBaServBackupScheduler::CBaServBackupScheduler()
    1.87 +{
    1.88 +}
    1.89 +
    1.90 +EXPORT_C CBaServBackupScheduler::~CBaServBackupScheduler()
    1.91 +{
    1.92 +}
    1.93 +
    1.94 +/**
    1.95 + *
    1.96 + * Set the error handler to aErrorHandler to the current scheduler.
    1.97 + *
    1.98 + * @param     "CBaServBackupSession* aErrorHandler"
    1.99 + *            The handler session.
   1.100 + */
   1.101 +EXPORT_C void CBaServBackupScheduler::SetErrorHandler(CBaServBackupSession* aErrorHandler)
   1.102 +	{
   1.103 +	iErrorHandler=aErrorHandler;
   1.104 +	}
   1.105 +
   1.106 +/**
   1.107 + *
   1.108 + * Handles the error aError.
   1.109 + *
   1.110 + * @param     "TInt aError"
   1.111 + *            The error.
   1.112 + */
   1.113 +EXPORT_C void CBaServBackupScheduler::Error(TInt aError) const
   1.114 +	{
   1.115 +	if (iErrorHandler)
   1.116 +		{
   1.117 +		iErrorHandler->HandleError(aError);
   1.118 +		}
   1.119 +	else if (aError!=KLeaveWithoutAlert)
   1.120 +		{
   1.121 +		// Handling the in this way implies that ServiceL should not leave.
   1.122 +		CActiveScheduler::Error(aError);
   1.123 +		}
   1.124 +	}
   1.125 +
   1.126 +/**
   1.127 +Class CBaServBackupSession::CReRegistrationTimer
   1.128 +*/
   1.129 +NONSHARABLE_CLASS(CBaServBackupSession::CReRegistrationTimer) : public CPeriodic
   1.130 +{
   1.131 +	public:
   1.132 +		static CReRegistrationTimer* NewL(TInt aPriority);
   1.133 +		static TInt ReRegistrationTimerCallBack(TAny* aPtr);
   1.134 +		
   1.135 +	protected:
   1.136 +		TInt RunError(TInt aError);
   1.137 +		
   1.138 +	private:
   1.139 +		CReRegistrationTimer(TInt aPriority);
   1.140 +		void HandleReRegistrationTimerCallBack();
   1.141 +
   1.142 +    public:
   1.143 +		CBaBackupServer* iBackupServer;
   1.144 +};
   1.145 +
   1.146 +/**
   1.147 +Class CBaBackupServer::CBaServCloseAllOperationTimer
   1.148 +*/
   1.149 +
   1.150 +NONSHARABLE_CLASS(CBaBackupServer::CBaServCloseAllOperationTimer): public CPeriodic
   1.151 +{
   1.152 +	public:
   1.153 +	    static CBaServCloseAllOperationTimer* NewL(CBaBackupServer* aBackupServer);
   1.154 +	   void ConstructL(CBaBackupServer* aBackupServer);
   1.155 +	   ~CBaServCloseAllOperationTimer();
   1.156 +	   void SetMessage(const RMessagePtr2& aPtr);
   1.157 +	   RMessagePtr2 Message();
   1.158 +	   TInt GetOperationCount();
   1.159 +	   void SetOperationCount(TInt aCount);
   1.160 +	   static TInt OperationTimerCallBack(TAny* aPtr);
   1.161 +	protected:
   1.162 +	   TInt RunError(TInt aError);
   1.163 +	private:
   1.164 +	   void HandleOperationTimerCallBack();
   1.165 +	   CBaServCloseAllOperationTimer();
   1.166 +	private:
   1.167 +	   RMessagePtr2 iCloseAllFilesMessage;
   1.168 +	   TInt16 iOperationCount;
   1.169 +	   CBaBackupServer* iBackupServer;
   1.170 +};
   1.171 +
   1.172 +//
   1.173 +// class CBaBackupServer
   1.174 +//
   1.175 +
   1.176 +/**
   1.177 + *
   1.178 + * Returns a pointer to <code>CBaBackupServer</code> object.
   1.179 + *
   1.180 + * @return   "CBaBackupServer"
   1.181 + *            A newly-constructed backup server object.
   1.182 + */
   1.183 +EXPORT_C CBaBackupServer* CBaBackupServer::NewL()
   1.184 +	{ // static
   1.185 +	CBaBackupServer* self=new(ELeave) CBaBackupServer(CActive::EPriorityStandard);
   1.186 +	return self;
   1.187 +	}
   1.188 +
   1.189 +/**
   1.190 + *
   1.191 + * Constructor.
   1.192 + *
   1.193 + * @param     "TInt aPriority"
   1.194 + *            The active object priority.
   1.195 + */
   1.196 +EXPORT_C CBaBackupServer::CBaBackupServer(TInt aPriority)
   1.197 +	: CServer2(aPriority)
   1.198 +	{}
   1.199 +/**
   1.200 + *
   1.201 + * Destructor.
   1.202 + *
   1.203 + */
   1.204 +EXPORT_C CBaBackupServer::~CBaBackupServer()
   1.205 +	{
   1.206 +	TDblQueIter<CSession2> iter(iSessionIter);
   1.207 +	iter.SetToFirst();
   1.208 +
   1.209 +	for (CSession2* session=iter++; session!=NULL; session=iter++)
   1.210 +		{
   1.211 +		delete session;
   1.212 +		}
   1.213 +	delete iShutdown;
   1.214 +	delete iExtension;
   1.215 +	delete iCloseAllFilesOperationTimer;
   1.216 +	}
   1.217 +
   1.218 +/**
   1.219 + *
   1.220 + * Completes the server construction by adding the server to the active scheduler and creating
   1.221 + * a <code>CShutdownServer</code> object.
   1.222 + *
   1.223 + */
   1.224 +EXPORT_C void CBaBackupServer::ConstructL()
   1.225 +	{
   1.226 +	StartL(__BACKUP_SERVER_NAME_V2);
   1.227 +	iExtension = new(ELeave) CBaBackupServerExt();
   1.228 +	iShutdown = new (ELeave) CShutdownServer;
   1.229 +	iShutdown->ConstructL();
   1.230 +	// ensure that the server still exits even if the 1st client fails to connect
   1.231 +	iShutdown->Start();
   1.232 +	iRegisteredFilesCount = 0;
   1.233 +	iCloseAllFilesOperationTimer = CBaBackupServer::CBaServCloseAllOperationTimer::NewL(this);
   1.234 +	iCloseAllOperationRunning = EFalse;
   1.235 +	
   1.236 +	//initialise the client message framework
   1.237 +	BSUL::CClientMessage::InitialiseFrameworkL(KServerData);
   1.238 +	}
   1.239 +
   1.240 +/**
   1.241 + *
   1.242 + * Sets the server to be busy with the aUniqueClientId client.
   1.243 + *
   1.244 + * @param     "TUint32 aUniqueClientId"
   1.245 + *            A unique client identifier.
   1.246 + */
   1.247 +EXPORT_C void CBaBackupServer::SetBusy(TUint32 aUniqueClientId)
   1.248 +	{
   1.249 +	iExtension->iUniqueBusyClientId=aUniqueClientId;
   1.250 +	}
   1.251 +
   1.252 +/**
   1.253 + *
   1.254 + * Returns <code>ETrue</code> if the client using the server is not the one identified by aUniqueClientId
   1.255 + * oterwise <code>EFalse</code>
   1.256 + *
   1.257 + * @param     "TUint32 aUniqueClientId"
   1.258 + *            A unique client identifier.
   1.259 + */
   1.260 +EXPORT_C TBool CBaBackupServer::IsOtherClientBusy(TUint32 aUniqueClientId) const
   1.261 +	{
   1.262 +	return (iExtension->iUniqueBusyClientId!=0 && iExtension->iUniqueBusyClientId!=aUniqueClientId);
   1.263 +	}
   1.264 +
   1.265 +/**
   1.266 + *
   1.267 + * Returns <code>ETrue</code> if the client using the server corresponds has aUniqueClientId as unique id
   1.268 + * oterwise <code>EFalse</code>
   1.269 + *
   1.270 + * @param     "TUint32 aUniqueClientId"
   1.271 + *            A unique client identifier id.
   1.272 + */
   1.273 +EXPORT_C TBool CBaBackupServer::IsClientBusy(TUint32 aUniqueClientId) const
   1.274 +	{
   1.275 +	return ((iExtension->iUniqueBusyClientId==aUniqueClientId) || 
   1.276 +			((iExtension->iCachedBusyClientId != 0) && (iExtension->iCachedBusyClientId == aUniqueClientId))); 
   1.277 +	}
   1.278 +
   1.279 +/**
   1.280 + *
   1.281 + * Handles the closing of all files by signaling the new file lock flag, aFlag, to all client.
   1.282 + *
   1.283 + * @param     "MBackupObserver::TFileLockFlags aFlag"
   1.284 + *            A file lock flag.
   1.285 + */
   1.286 +EXPORT_C void CBaBackupServer::CloseAllFilesL(MBackupObserver::TFileLockFlags aFlag)
   1.287 +	{
   1.288 +	// Set the close all operation flag and the reregistration counter to zero
   1.289 +	iCloseAllOperationRunning = ETrue;
   1.290 +	iSessionLockReRegistrationCount = 0;
   1.291 +	
   1.292 +	// cleanup that calls RestartAll if required
   1.293 +	TDblQueIter<CSession2> iter(iSessionIter);
   1.294 +	iter.SetToFirst();
   1.295 +
   1.296 +	for (CSession2* session=iter++; session!=NULL; session=iter++)
   1.297 +		{
   1.298 +		static_cast<CBaServBackupSession*>(session)->SignalReleaseAllFileLocksL(aFlag);
   1.299 +		}
   1.300 +	}
   1.301 +
   1.302 +/**
   1.303 + *
   1.304 + * Signals to all clients of getting the lock of their respective files.
   1.305 + *
   1.306 + */
   1.307 +EXPORT_C void CBaBackupServer::RestartAll()
   1.308 +	{
   1.309 +	TDblQueIter<CSession2> iter(iSessionIter);
   1.310 +	iter.SetToFirst();
   1.311 +
   1.312 +	for (CSession2* session=iter++; session!=NULL; session=iter++)
   1.313 +		{
   1.314 +		static_cast<CBaServBackupSession*>(session)->SignalRetakeAllFileLocks();
   1.315 +		}
   1.316 +	}
   1.317 +
   1.318 +/**
   1.319 + *
   1.320 + * Allows any subclass of <code>CBaBackupServer</code> of completing the closing of files.
   1.321 + * The server will lose the ownership of aClosedFiles object, which implies it is up to this virtual
   1.322 + * function to deal with it in order to avoid a memory leak.
   1.323 + *
   1.324 + * @param     "CArrayFix<CBaServBackupSession::TClosedFile>* aClosedFiles"
   1.325 + *            An array of closed files.
   1.326 + */
   1.327 +EXPORT_C void CBaBackupServer::CompleteClosingFiles(CArrayFix<CBaServBackupSession::TClosedFile>* aClosedFiles)
   1.328 +	{
   1.329 +	delete aClosedFiles;
   1.330 +	}
   1.331 +
   1.332 +/**
   1.333 + *
   1.334 + * Allows application framework backup code to check if all registerd files have beem updated
   1.335 + *
   1.336 + */
   1.337 +EXPORT_C TBool CBaBackupServer::HaveAllCloseAllFilesClientsReRegistered()
   1.338 +	{
   1.339 +	return((iRegisteredFilesCount == iSessionLockReRegistrationCount) ? ETrue : EFalse);
   1.340 +	}
   1.341 +
   1.342 +void CBaBackupServer::CloseFileL(MBackupObserver::TFileLockFlags aFlag,const TDesC& aFileName)
   1.343 +	{
   1.344 +	TDblQueIter<CSession2> iter(iSessionIter);
   1.345 +	iter.SetToFirst();
   1.346 +
   1.347 +	for (CSession2* session=iter++; session!=NULL; session=iter++)
   1.348 +		{
   1.349 +		static_cast<CBaServBackupSession*>(session)->SignalReleaseFileLockL(aFlag,aFileName);
   1.350 +		}
   1.351 +	}
   1.352 +
   1.353 +void CBaBackupServer::RestartFile(const TDesC& aFileName)
   1.354 +	{
   1.355 +	TDblQueIter<CSession2> iter(iSessionIter);
   1.356 +	iter.SetToFirst();
   1.357 +
   1.358 +	for (CSession2* session=iter++; session!=NULL; session=iter++)
   1.359 +		{
   1.360 +		static_cast<CBaServBackupSession*>(session)->SignalRetakeFileLocks(aFileName);
   1.361 +		}
   1.362 +	}
   1.363 +
   1.364 +/**
   1.365 + *
   1.366 + * Creates a server-side client <code>CBaServBackupSession</code> session object by checking first if
   1.367 + * the version of the server is compatible with the client.
   1.368 + *
   1.369 + * @param     "const TVersion &aVersion"
   1.370 + *            Version information supplied by the client.
   1.371 + */
   1.372 +EXPORT_C CSession2* CBaBackupServer::NewSessionL(const TVersion &aVersion, const RMessage2& /*aMessage*/) const
   1.373 +	{
   1.374 +	TVersion ver(KBakServMajorVN,KBakServMinorVN,KBakServBuildVN);
   1.375 +	if (!User::QueryVersionSupported(ver,aVersion))
   1.376 +		User::Leave(KErrNotSupported);
   1.377 +//
   1.378 +	return CBaServBackupSession::NewL();
   1.379 +	}
   1.380 +
   1.381 +/**
   1.382 + *
   1.383 + * Signals to all clients the aBackupOperationAttributes.
   1.384 + *
   1.385 + * @param     "const TBackupOperationAttributes& aBackupOperationAttributes"
   1.386 + *            Backup operation attributes.
   1.387 + */
   1.388 +EXPORT_C void CBaBackupServer::SignalBackupOperation(const TBackupOperationAttributes& aBackupOperationAttributes)
   1.389 +	{
   1.390 +	TDblQueIter<CSession2> iter(iSessionIter);
   1.391 +	iter.SetToFirst();
   1.392 +
   1.393 +	for (CSession2* session=iter++; session!=NULL; session=iter++)
   1.394 +		{
   1.395 +		static_cast<CBaServBackupSession*>(session)->SignalBackupOperation(aBackupOperationAttributes);
   1.396 +		}
   1.397 +	// Cache session id if starting backup
   1.398 +	if (aBackupOperationAttributes.iOperation == MBackupOperationObserver::EStart)
   1.399 +			iExtension->iCachedBusyClientId = iExtension->iUniqueBusyClientId;
   1.400 +	}
   1.401 +
   1.402 +void CBaBackupServer::AddSession()
   1.403 +	{
   1.404 +	iShutdown->Cancel();
   1.405 +	++iSessionCount;
   1.406 +	}
   1.407 +
   1.408 +void CBaBackupServer::DropSession()
   1.409 +	{
   1.410 +	if (--iSessionCount==0)
   1.411 +		{
   1.412 +		iShutdown->Start();
   1.413 +		}
   1.414 +	}
   1.415 +
   1.416 +/*
   1.417 + * Check to see if a CloseAll opertation is in progress
   1.418 + * 
   1.419 + */
   1.420 +TBool CBaBackupServer::IsCloseAllOperationRunning()
   1.421 +	{
   1.422 +	return iCloseAllOperationRunning;
   1.423 +	}
   1.424 +
   1.425 +/*
   1.426 + * Set value of IsCloseAllOperationRunning
   1.427 + * 
   1.428 + */
   1.429 +EXPORT_C void CBaBackupServer::SetCloseAllOperationRunningState(TBool aRunning)
   1.430 +	{
   1.431 +	iCloseAllOperationRunning = aRunning;
   1.432 +	}
   1.433 +
   1.434 +/**
   1.435 + *
   1.436 + * This timer will only be created in cases of no derived backup server
   1.437 + *
   1.438 + */
   1.439 +void CBaBackupServer::StartCloseAllFilesOperationTimer(const RMessagePtr2& aPtr)
   1.440 +	{
   1.441 +	// Store the CloseAll message in case we need to Complete on a timeout
   1.442 +	iCloseAllFilesOperationTimer->SetMessage(aPtr);
   1.443 +	
   1.444 +	// If hardware use patchable constant if not default to 3 seconds
   1.445 +	iCloseAllFilesOperationTimer->Start(KBaBackupCloseallFilesTimeout, KBaBackupCloseallFilesTimeout, TCallBack(CBaBackupServer::CBaServCloseAllOperationTimer::OperationTimerCallBack, iCloseAllFilesOperationTimer));
   1.446 +	}
   1.447 +
   1.448 +/**
   1.449 + * Handle an error from CBaServBackupSession::ServiceL()
   1.450 + * A bad descriptor error implies a badly programmed client, so panic it;
   1.451 + * otherwise report the error to the client
   1.452 + *
   1.453 + * @param     "TInt aError"
   1.454 + *            The error.
   1.455 + */
   1.456 +EXPORT_C TInt CBaBackupServer::RunError(TInt aError)
   1.457 +	{
   1.458 +	if (aError==KErrBadDescriptor)
   1.459 +		{
   1.460 +		PanicClient(Message(), EBufferOverflow);
   1.461 +		}
   1.462 +	else
   1.463 +		{
   1.464 +		Message().Complete(aError);
   1.465 +		}
   1.466 +	//
   1.467 +	// The leave will result in an early return from CServer::RunL(), skipping
   1.468 +	// the call to request another message. So do that now in order to keep the
   1.469 +	// server running.
   1.470 +	ReStart();
   1.471 +	return KErrNone;	// handled the error fully
   1.472 +	}
   1.473 +
   1.474 +//
   1.475 +// class CBaBackupServer::CBaServCloseAllOperationTimer
   1.476 +//
   1.477 +
   1.478 +/**
   1.479 +@internalComponent
   1.480 +*/
   1.481 +CBaBackupServer::CBaServCloseAllOperationTimer* CBaBackupServer::CBaServCloseAllOperationTimer::NewL(CBaBackupServer* aBackupServer)
   1.482 +	{ // static
   1.483 +	CBaBackupServer::CBaServCloseAllOperationTimer* self=new(ELeave) CBaBackupServer::CBaServCloseAllOperationTimer();
   1.484 +	CleanupStack::PushL(self);
   1.485 +	self->ConstructL(aBackupServer);
   1.486 +	CleanupStack::Pop(); // self
   1.487 +	CActiveScheduler::Add(self);
   1.488 +	return self;
   1.489 +	}
   1.490 +
   1.491 +/**
   1.492 +@internalComponent
   1.493 +*/
   1.494 +
   1.495 +void CBaBackupServer::CBaServCloseAllOperationTimer::ConstructL(CBaBackupServer* aBackupServer)
   1.496 +	{
   1.497 +	CTimer::ConstructL();
   1.498 +	iBackupServer = aBackupServer;
   1.499 +	iOperationCount = 0;
   1.500 +	}
   1.501 +/**
   1.502 +@internalComponent
   1.503 +*/
   1.504 +
   1.505 +TInt CBaBackupServer::CBaServCloseAllOperationTimer::GetOperationCount()
   1.506 +{
   1.507 +	return iOperationCount;	
   1.508 +}
   1.509 +
   1.510 +/**
   1.511 +@internalComponent
   1.512 +*/
   1.513 +
   1.514 +void CBaBackupServer::CBaServCloseAllOperationTimer::SetOperationCount(TInt aCount)
   1.515 +{
   1.516 +	iOperationCount = aCount;
   1.517 +}
   1.518 +
   1.519 +/**
   1.520 +@internalComponent
   1.521 +*/
   1.522 +
   1.523 +TInt CBaBackupServer::CBaServCloseAllOperationTimer::RunError(TInt aError)
   1.524 +	{
   1.525 +	if (aError==KLeaveWithoutAlert)
   1.526 +		{
   1.527 +		return KErrNone;
   1.528 +		}
   1.529 +	return aError;
   1.530 +	}
   1.531 +	
   1.532 +/**
   1.533 +@internalComponent
   1.534 +*/
   1.535 +CBaBackupServer::CBaServCloseAllOperationTimer::CBaServCloseAllOperationTimer()
   1.536 +	: CPeriodic(CActive::EPriorityStandard)
   1.537 +	{ ;	}
   1.538 +	
   1.539 +/**
   1.540 +@internalComponent
   1.541 +*/
   1.542 +CBaBackupServer::CBaServCloseAllOperationTimer::~CBaServCloseAllOperationTimer()
   1.543 +	{
   1.544 +	if (IsActive())
   1.545 +		Cancel();	
   1.546 +	}
   1.547 +
   1.548 +/**
   1.549 +@internalComponent
   1.550 +*/
   1.551 +void CBaBackupServer::CBaServCloseAllOperationTimer::SetMessage(const RMessagePtr2& aPtr)
   1.552 +	{
   1.553 +	iCloseAllFilesMessage = aPtr;
   1.554 +	}
   1.555 +
   1.556 +/**
   1.557 +@internalComponent
   1.558 +*/
   1.559 +RMessagePtr2 CBaBackupServer::CBaServCloseAllOperationTimer::Message()
   1.560 +	{
   1.561 +	return iCloseAllFilesMessage;
   1.562 +	}
   1.563 +	
   1.564 +/**
   1.565 +@internalComponent
   1.566 +*/
   1.567 +TInt CBaBackupServer::CBaServCloseAllOperationTimer::OperationTimerCallBack(TAny* aPtr)
   1.568 +	{ // static
   1.569 +	TRAP_IGNORE(REINTERPRET_CAST(CBaBackupServer::CBaServCloseAllOperationTimer*,aPtr)->HandleOperationTimerCallBack());
   1.570 +	return 0;
   1.571 +	}
   1.572 +
   1.573 +/**
   1.574 +@internalComponent
   1.575 +*/
   1.576 +void CBaBackupServer::CBaServCloseAllOperationTimer::HandleOperationTimerCallBack()
   1.577 +	{
   1.578 +	TBool finished = iBackupServer->HaveAllCloseAllFilesClientsReRegistered();
   1.579 +	TInt retCode;
   1.580 +	if (finished || (iOperationCount == KBakServMaxOperationTimerLoops))
   1.581 +		{
   1.582 +		if (finished)
   1.583 +			{
   1.584 +			retCode = KErrNone;
   1.585 +			}
   1.586 +		else
   1.587 +			{
   1.588 +			retCode = KErrLocked;
   1.589 +			}
   1.590 +		
   1.591 +		// One way or another CloseAll is finished at this point
   1.592 +		iBackupServer->SetCloseAllOperationRunningState(EFalse);
   1.593 +		
   1.594 +		iCloseAllFilesMessage.Complete(retCode);
   1.595 +		Cancel();
   1.596 +		}
   1.597 +	else
   1.598 +		{
   1.599 +		iOperationCount++;
   1.600 +		if (IsActive())
   1.601 +			{
   1.602 +			Cancel();
   1.603 +
   1.604 +			// If hardware use patchable constant if not default to 3 seconds
   1.605 +			Start(KBaBackupCloseallFilesTimeout, KBaBackupCloseallFilesTimeout, TCallBack(CBaBackupServer::CBaServCloseAllOperationTimer::OperationTimerCallBack,this));
   1.606 +			}
   1.607 +		}
   1.608 +	}
   1.609 +
   1.610 +//
   1.611 +// class CBaServBackupMessageQueue
   1.612 +//
   1.613 +
   1.614 +inline CBaServBackupMessageQueue::TQueueItem::TQueueItem(HBufC* aFileName,TInt aOperation)
   1.615 +	: iFileName(aFileName), iOperation(aOperation)
   1.616 +	{}
   1.617 +
   1.618 +CBaServBackupMessageQueue* CBaServBackupMessageQueue::NewL()
   1.619 +	{ // static
   1.620 +	CBaServBackupMessageQueue* self=new(ELeave) CBaServBackupMessageQueue();
   1.621 +	return self;
   1.622 +	}
   1.623 +
   1.624 +CBaServBackupMessageQueue::~CBaServBackupMessageQueue()
   1.625 +	{
   1.626 +	const TInt count=iQueue.Count();
   1.627 +	for (TInt ii=0;ii<count;ii++)
   1.628 +		{
   1.629 +		delete iQueue[ii].iFileName;
   1.630 +		}
   1.631 +	iQueue.Reset();
   1.632 +	iQueue.Close();
   1.633 +	}
   1.634 +
   1.635 +void CBaServBackupMessageQueue::AddItemL(const TDesC& aFileName,MBackupObserver::TFileLockFlags aFlag)
   1.636 +	{
   1.637 +	const TInt count=iQueue.Count();
   1.638 +	for (TInt ii=0;ii<count;ii++)
   1.639 +		{
   1.640 +		TQueueItem& item=iQueue[ii];
   1.641 +		if(aFileName.MatchF(*item.iFileName) == KErrNone)
   1.642 +			{
   1.643 +			if (item.iOperation==MBackupObserver::EReleaseLockReadOnly && aFlag==MBackupObserver::EReleaseLockNoAccess)
   1.644 +				{
   1.645 +				item.iOperation=MBackupObserver::EReleaseLockNoAccess;
   1.646 +				}
   1.647 +			else if (item.iOperation!=MBackupObserver::EReleaseLockNoAccess)
   1.648 +				{
   1.649 +				HBufC* file=aFileName.AllocLC();
   1.650 +				TQueueItem item(file,aFlag);
   1.651 +				User::LeaveIfError(iQueue.Insert(item,ii));
   1.652 +				CleanupStack::Pop(); // file
   1.653 +				}
   1.654 +			return;
   1.655 +			}
   1.656 +		}
   1.657 +	HBufC* file=aFileName.AllocLC();
   1.658 +	HBufC* copy=aFileName.AllocLC();
   1.659 +	TQueueItem item(file,aFlag);
   1.660 +	User::LeaveIfError(iQueue.Append(item));
   1.661 +	item=TQueueItem(copy,-1);
   1.662 +	const TInt err=iQueue.Append(item);
   1.663 +	if (err!=KErrNone)
   1.664 +		{
   1.665 +		iQueue.Remove(iQueue.Count()-1);
   1.666 +		User::Leave(err);
   1.667 +		}
   1.668 +	CleanupStack::Pop(2); // copy, file
   1.669 +	}
   1.670 +
   1.671 +void CBaServBackupMessageQueue::AddItem(const TDesC& aFileName)
   1.672 +	{
   1.673 +	const TInt count=iQueue.Count();
   1.674 +	for (TInt ii=0;ii<count;ii++)
   1.675 +		{
   1.676 +		TQueueItem& item=iQueue[ii];
   1.677 +		if (aFileName.MatchF(*item.iFileName) == KErrNone && item.iOperation==-1)
   1.678 +			{
   1.679 +			item.iOperation=0;
   1.680 +			break;
   1.681 +			}
   1.682 +		}
   1.683 +	}
   1.684 +
   1.685 +TBool CBaServBackupMessageQueue::IsEmpty() const
   1.686 +	{
   1.687 +	return HeadIndex()==KErrNotFound;
   1.688 +	}
   1.689 +
   1.690 +void CBaServBackupMessageQueue::RemoveHead()
   1.691 +	{
   1.692 +	const TInt index=HeadIndex();
   1.693 +	if (index!=KErrNotFound)
   1.694 +		{
   1.695 +		delete iQueue[index].iFileName;
   1.696 +		iQueue.Remove(index);
   1.697 +		iQueue.Compress();
   1.698 +		}
   1.699 +	}
   1.700 +
   1.701 +void CBaServBackupMessageQueue::RemoveItem(const TDesC& aFileName)
   1.702 +	{
   1.703 +	const TInt count=iQueue.Count();
   1.704 +	for (TInt ii=count-1;ii>=0;ii--)
   1.705 +		{
   1.706 +		const TQueueItem& item=iQueue[ii];
   1.707 +		if (aFileName.MatchF(*item.iFileName) == KErrNone)
   1.708 +			{
   1.709 +			delete item.iFileName;
   1.710 +			iQueue.Remove(ii);
   1.711 +			iQueue.Compress();
   1.712 +			}
   1.713 +		}
   1.714 +	}
   1.715 +
   1.716 +void CBaServBackupMessageQueue::GetHead(TDes& aFileName,MBackupObserver::TFileLockFlags& aFlag) const
   1.717 +	{
   1.718 +	aFileName.Zero();
   1.719 +	const TInt index=HeadIndex();
   1.720 +	if (index!=KErrNotFound)
   1.721 +		{
   1.722 +		const TQueueItem& item=iQueue[index];
   1.723 +		aFileName=item.iFileName->Des();
   1.724 +		aFlag=(MBackupObserver::TFileLockFlags)item.iOperation;
   1.725 +		}
   1.726 +	}
   1.727 +
   1.728 +TInt CBaServBackupMessageQueue::HeadIndex() const
   1.729 +	{
   1.730 +	TInt index=KErrNotFound;
   1.731 +	const TInt count=iQueue.Count();
   1.732 +	for (TInt ii=0;ii<count;ii++)
   1.733 +		{
   1.734 +		const TQueueItem& item=iQueue[ii];
   1.735 +		if (item.iOperation!=ENoOp)
   1.736 +			{
   1.737 +			index=ii;
   1.738 +			break;
   1.739 +			}
   1.740 +		}
   1.741 +	return index;
   1.742 +	}
   1.743 +
   1.744 +//
   1.745 +// class CBaServBackupSession
   1.746 +//
   1.747 +
   1.748 +CBaServBackupSession* CBaServBackupSession::NewL()
   1.749 +	{ // static
   1.750 +	CBaServBackupSession* self=new(ELeave) CBaServBackupSession();
   1.751 +	CleanupStack::PushL(self);
   1.752 +	self->ConstructL();
   1.753 +	CleanupStack::Pop(); // self
   1.754 +	return self;
   1.755 +	}
   1.756 +
   1.757 +/**
   1.758 + *
   1.759 + * Constructor.
   1.760 + *
   1.761 + * @param     "RThread aClient"
   1.762 + *            The client thread for which this server-side client session is being constructed.
   1.763 + */
   1.764 +EXPORT_C CBaServBackupSession::CBaServBackupSession()
   1.765 +	: CSession2()
   1.766 +	{
   1.767 +	iUniqueClientId = (TUint32)this;
   1.768 +	}
   1.769 +
   1.770 +/**
   1.771 + *
   1.772 + * Destructor.
   1.773 + *
   1.774 + */
   1.775 +EXPORT_C CBaServBackupSession::~CBaServBackupSession()
   1.776 +	{
   1.777 +	CBaBackupServer* server=BackupServer();
   1.778 +	if (server->IsClientBusy(iUniqueClientId))
   1.779 +		{
   1.780 +		RestartAll();
   1.781 +		if (server->IsBackupOperationRunning())
   1.782 +			{
   1.783 +			TBackupOperationAttributes backupOpAtt(MBackupObserver::ETakeLock, MBackupOperationObserver::EAbort);
   1.784 +			server->SignalBackupOperation(backupOpAtt);
   1.785 +			server->SetBackupOperationRunning(EFalse);
   1.786 +			}
   1.787 +		server->SetBusy(0);
   1.788 +		}
   1.789 +
   1.790 +	if (iFileLockObservers)
   1.791 +		{
   1.792 +		server->DecrementRegisteredFilesCount(iFileLockObservers->Count());	
   1.793 +		}
   1.794 +
   1.795 +	delete iClosedFiles;
   1.796 +	delete iFileLockObservers;
   1.797 +	delete iReleasedFiles;
   1.798 +	delete iMessageQueue;
   1.799 +	delete iReRegistrationTimer;
   1.800 +	iReRegistrationTimer = 0;
   1.801 +	server->DropSession();
   1.802 +	}
   1.803 +
   1.804 +/**
   1.805 + *
   1.806 + * Completes the session construction by creating a <code>CBaServBackupMessageQueue</code> object.
   1.807 + *
   1.808 + */
   1.809 +EXPORT_C void CBaServBackupSession::ConstructL()
   1.810 +	{
   1.811 +	iMessageQueue=CBaServBackupMessageQueue::NewL();
   1.812 +
   1.813 +	// Cannot set iBackupServer in CReRegistrationTimer at this point but must be done before call to Start
   1.814 +	iReRegistrationTimer=CBaServBackupSession::CReRegistrationTimer::NewL(CActive::EPriorityStandard);
   1.815 +	}
   1.816 +
   1.817 +/**
   1.818 + *
   1.819 + * Completes the construction of this <code>CBaServBackupSession</code> session by just doing a base call class.
   1.820 + * It also notify the server that a new session has been created.
   1.821 + *
   1.822 + * @param		"const CServer& aServer"
   1.823 + *				The server active object which is responsible for this session
   1.824 + */
   1.825 +EXPORT_C void CBaServBackupSession::CreateL()
   1.826 +	{
   1.827 +	BackupServer()->AddSession();
   1.828 +	}
   1.829 +
   1.830 +void CBaServBackupSession::SignalReleaseAllFileLocksL(MBackupObserver::TFileLockFlags aFlag)
   1.831 +	{
   1.832 +	CBaBackupServer* server=BackupServer();
   1.833 +	if (iFileLockObservers)
   1.834 +		{
   1.835 +		const TInt count=iFileLockObservers->Count();
   1.836 +		for (TInt ii=0;ii<count;ii++)
   1.837 +			{
   1.838 +			TFileName name=(*iFileLockObservers)[ii];
   1.839 +			server->CloseFileL(aFlag,name);
   1.840 +			}
   1.841 +		}
   1.842 +	}
   1.843 +
   1.844 +void CBaServBackupSession::SignalRetakeAllFileLocks()
   1.845 +	{
   1.846 +//	CBaBackupServer* server=BackupServer();
   1.847 +	if (iReleasedFiles)
   1.848 +		{
   1.849 +		const TInt count=iReleasedFiles->Count();
   1.850 +		for (TInt ii=count-1;ii>=0;ii--)
   1.851 +			{
   1.852 +			TFileName name=(*iReleasedFiles)[ii];
   1.853 +//			server->RestartFile(name);
   1.854 +			SignalRetakeFileLocks(name);
   1.855 +			}
   1.856 +		}
   1.857 +	}
   1.858 +
   1.859 +LOCAL_C void CleanupCloseFail(TAny* aPtr)
   1.860 +	{
   1.861 +	CDesCArray* array=REINTERPRET_CAST(CDesCArray*,aPtr);
   1.862 +	array->Delete(array->Count()-1);
   1.863 +	}
   1.864 +
   1.865 +void CBaServBackupSession::SignalReleaseFileLockL(MBackupObserver::TFileLockFlags aFlag,const TDesC& aFileName)
   1.866 +	{
   1.867 +	TInt pos;
   1.868 +	if (iFileLockObservers && iFileLockObservers->Find(aFileName,pos)==KErrNone)
   1.869 +		{
   1.870 +		if (iReleasedFiles==NULL)
   1.871 +			{
   1.872 +			iReleasedFiles=new(ELeave) CDesCArraySeg(1);
   1.873 +			}
   1.874 +		const TBool addedReleasedFile=iReleasedFiles->Find(aFileName,pos)!=KErrNone;
   1.875 +		if (addedReleasedFile)
   1.876 +			{
   1.877 +			iReleasedFiles->AppendL(aFileName);
   1.878 +			CleanupStack::PushL(TCleanupItem(CleanupCloseFail,iReleasedFiles));
   1.879 +			}
   1.880 +		iMessageQueue->AddItemL(aFileName,aFlag);
   1.881 +		if (!iNotificationPullMsg.IsNull())
   1.882 +  			{
   1.883 +  			iNotificationPullMsg.Complete(KErrNone);
   1.884 +
   1.885 +  			// Okay - if this is part of a CloseAll operation we need to kick off a ReRegistration timer
   1.886 +  			if (BackupServer()->IsCloseAllOperationRunning())
   1.887 +  				{
   1.888 +  				// Set backup server for the timer
   1.889 +  				iReRegistrationTimer->iBackupServer = BackupServer();
   1.890 +
   1.891 +  				// If hardware use patchable constant if not default to 3 seconds
   1.892 +  				iReRegistrationTimer->Start(KBaBackupFileLockReRegistrationTimeout, KBaBackupFileLockReRegistrationTimeout, TCallBack(CBaServBackupSession::CReRegistrationTimer::ReRegistrationTimerCallBack, iReRegistrationTimer));  				
   1.893 +  				}
   1.894 +
   1.895 +  			}
   1.896 +		if (addedReleasedFile)
   1.897 +			{
   1.898 +			CleanupStack::Pop(); // CleanupCloseFail
   1.899 +			}
   1.900 +		}
   1.901 +	}
   1.902 +
   1.903 +void CBaServBackupSession::SignalRetakeFileLocks(const TDesC& aFileName)
   1.904 +	{
   1.905 +	if (iReleasedFiles)
   1.906 +		{
   1.907 +		const TInt count=iReleasedFiles->Count();
   1.908 +		for (TInt ii=count-1;ii>=0;ii--)
   1.909 +			{
   1.910 +			TFileName name=(*iReleasedFiles)[ii];
   1.911 +			if (name.MatchF(aFileName)==0)
   1.912 +				{
   1.913 +				iMessageQueue->AddItem(aFileName);
   1.914 +				if (!iNotificationPullMsg.IsNull())
   1.915 +  					{
   1.916 +  					iNotificationPullMsg.Complete(KErrNone);
   1.917 +  					}
   1.918 +				iReleasedFiles->Delete(ii);
   1.919 +				}
   1.920 +			}
   1.921 +		if (iReleasedFiles->Count()==0)
   1.922 +			{
   1.923 +			delete iReleasedFiles;
   1.924 +			iReleasedFiles=NULL;
   1.925 +			if (iClosedFiles==NULL && BackupServer()->IsClientBusy(iUniqueClientId))
   1.926 +				{
   1.927 +				BackupServer()->SetBusy(0);
   1.928 +				}
   1.929 +			}
   1.930 +		}
   1.931 +	}
   1.932 +
   1.933 +/**
   1.934 + *
   1.935 + * Allows the session to handle the error.
   1.936 + *
   1.937 + * @param		"TInt aError"
   1.938 + *				The error.
   1.939 + */
   1.940 +EXPORT_C void CBaServBackupSession::HandleError(TInt aError)
   1.941 +	{
   1.942 +	if (aError==KLeaveWithoutAlert)
   1.943 +		{
   1.944 +		CBaServBackupScheduler::Current()->SetErrorHandler(NULL);
   1.945 +		}
   1.946 +	}
   1.947 +
   1.948 +void CBaServBackupSession::DoServiceL(TCompletionType& aCompleteType)
   1.949 +	{
   1.950 +	switch (iClientMessage->Function())
   1.951 +		{
   1.952 +	case EBakOpCodeEventReady:
   1.953 +		{
   1.954 +		HandleEventReadyL();
   1.955 +		aCompleteType = ECompleteAsync;
   1.956 +		}
   1.957 +		break;
   1.958 +	case EBakOpCodeStopNotifications:
   1.959 +		{
   1.960 +		StopNotifications();
   1.961 +		}
   1.962 +		break;
   1.963 +	case EBakOpCodeGetEvent:
   1.964 +		GetEventL();
   1.965 +		break;
   1.966 +	case EBakOpCodeCloseAllFiles:
   1.967 +		{
   1.968 +		aCompleteType = CloseAllFilesL(iClientMessage->Message());
   1.969 +		}
   1.970 +		break;
   1.971 +	case EBakOpCodeRestartAll:
   1.972 +		RestartAll();
   1.973 +		break;
   1.974 +	case EBakOpCodeCloseFile:
   1.975 +		CloseFileL();
   1.976 +		break;
   1.977 +	case EBakOpCodeRestartFile:
   1.978 +		RestartFileL();
   1.979 +		break;
   1.980 +	case EBakOpCodeNotifyLockChange:
   1.981 +		NotifyLockChangeL();
   1.982 +		break;
   1.983 +	case EBakOpCodeNotifyLockChangeCancel:
   1.984 +		NotifyLockChangeCancelL();
   1.985 +		break;
   1.986 +	case EBakOpCodeNotifyBackupOperation:
   1.987 +		NotifyBackupOperationL();
   1.988 +		break;
   1.989 +	case EBakOpCodeCancelOutstandingBackupOperationEvent:
   1.990 +		{
   1.991 +		iBackupOperationObserverPresent = EFalse;
   1.992 +		if (!iBackupOperationMessagePtr.IsNull())
   1.993 +			{
   1.994 +			GetBackupOperationEventL(iBackupOperationMessagePtr);
   1.995 +			iBackupOperationMessagePtr.Complete(KErrCancel);
   1.996 +			}
   1.997 +		}
   1.998 +		break;
   1.999 +	case EBakOpCodeGetBackupOperationState:
  1.1000 +		GetBackupOperationStateL();
  1.1001 +		break;
  1.1002 +	case EBakOpCodeBackupOperationEventReady:
  1.1003 +		BackupOperationEventReadyL();
  1.1004 +		aCompleteType = ECompleteAsync;
  1.1005 +		break;
  1.1006 +	case EBakOpCodeGetBackupOperationEvent:
  1.1007 +		GetBackupOperationEventL(iClientMessage->Message());
  1.1008 +		break;
  1.1009 +	case EBakOpCodeSetBackupOperationObserverIsPresent:
  1.1010 +		{
  1.1011 +		iBackupOperationObserverPresent = iClientMessage->GetIntL(0);
  1.1012 +		}
  1.1013 +		break;
  1.1014 +	default:
  1.1015 +		User::Leave(KErrNotSupported);
  1.1016 +		break;
  1.1017 +		}
  1.1018 +	}
  1.1019 +
  1.1020 +
  1.1021 +/**
  1.1022 + *
  1.1023 + * Handles the servicing of client requests passed to the backup server.
  1.1024 + *
  1.1025 + * @param		"const RMessage& aMessage"
  1.1026 + *				The message containing the client request.
  1.1027 + */
  1.1028 +EXPORT_C void CBaServBackupSession::ServiceL(const RMessage2& aMessage)
  1.1029 +	{
  1.1030 +	
  1.1031 +	TCompletionType completionType = ECompleteSync;
  1.1032 +	
  1.1033 +	BSUL::CClientMessage* clientMessage = 0;
  1.1034 +	clientMessage = BSUL::CClientMessage::NewL(aMessage);
  1.1035 +	
  1.1036 +	//Push iClientMessage onto the cleanupstack. Although an instance variable, 
  1.1037 +	//the lifetime of the object is contained to this function so it needs to
  1.1038 +	//be pushed and popped here as it is not deleted in the destructor
  1.1039 +	CleanupStack::PushL(clientMessage);
  1.1040 +	
  1.1041 +	//Validate the message
  1.1042 +	TRAPD(error, clientMessage->ValidateL());
  1.1043 +	
  1.1044 +	iClientMessage = clientMessage;
  1.1045 +	
  1.1046 +	if(error == KErrNone)	
  1.1047 +		{
  1.1048 +		TRAP(error, DoServiceL(completionType));
  1.1049 +		}
  1.1050 +	
  1.1051 +	if(completionType == ECompleteSync)
  1.1052 +		{
  1.1053 +		if (error==KLeaveWithoutAlert)
  1.1054 +			{
  1.1055 +			CBaServBackupScheduler::Current()->SetErrorHandler(NULL);
  1.1056 +			}
  1.1057 +		else
  1.1058 +			{
  1.1059 +			iClientMessage->CompleteRequestL(error);
  1.1060 +			}
  1.1061 +		}
  1.1062 +	
  1.1063 +	//Pop and destroy message
  1.1064 +	CleanupStack::PopAndDestroy(clientMessage);
  1.1065 +	clientMessage = NULL;
  1.1066 +	iClientMessage = NULL;
  1.1067 +	}
  1.1068 +
  1.1069 +void CBaServBackupSession::HandleEventReadyL()
  1.1070 +	{
  1.1071 +	if (iReRegistrationTimer->IsActive())
  1.1072 +		{ // If timer is still active (ie not timed out) we need to increment the counter and cancel the timer
  1.1073 +		BackupServer()->IncrementFilesReRegistrationCount();	
  1.1074 +		iReRegistrationTimer->Cancel();
  1.1075 +		}
  1.1076 +		// else timer is already inactive because it's expired
  1.1077 +	
  1.1078 +	if (iMessageQueue->IsEmpty())
  1.1079 +		{
  1.1080 +		iNotificationPullMsg = iClientMessage->Message();
  1.1081 +		}	
  1.1082 +	else
  1.1083 +		{
  1.1084 +		iClientMessage->CompleteRequestL(KErrNone);
  1.1085 +		}
  1.1086 +	}
  1.1087 +
  1.1088 +const TInt KEventFileNameOffset=1;
  1.1089 +
  1.1090 +void CBaServBackupSession::GetEventL()
  1.1091 +	{
  1.1092 +	TFileName fileName;
  1.1093 +	MBackupObserver::TFileLockFlags fileFlag;
  1.1094 +	if(!iMessageQueue->IsEmpty())
  1.1095 +		{
  1.1096 +		iMessageQueue->GetHead(fileName,fileFlag);
  1.1097 +		TBuf<KEventFileNameOffset> num;
  1.1098 +		num.Num((TInt)fileFlag);
  1.1099 +		
  1.1100 +		iClientMessage->WriteL(0,num,0);
  1.1101 +		
  1.1102 +		iClientMessage->WriteL(0,fileName,KEventFileNameOffset);
  1.1103 +	
  1.1104 +		iMessageQueue->RemoveHead();	
  1.1105 +		}
  1.1106 +	else
  1.1107 +		{
  1.1108 +		iClientMessage->PanicClient(KPanic,ENoEventToFetch);
  1.1109 +		User::Leave(KLeaveWithoutAlert);
  1.1110 +		}
  1.1111 +	}
  1.1112 +
  1.1113 +void CBaServBackupSession::CleanupCloseAllFiles(TAny* aPtr)
  1.1114 +	{ // static
  1.1115 +	CBaServBackupSession* self=REINTERPRET_CAST(CBaServBackupSession*,aPtr);
  1.1116 +	delete self->iClosedFiles;
  1.1117 +	self->iClosedFiles=NULL;
  1.1118 +	self->BackupServer()->RestartAll();
  1.1119 +	}
  1.1120 +
  1.1121 +/**
  1.1122 + Asks the server to close all files. This function may leave in case the server is busy.
  1.1123 + If the requesting client is the current busy client and it has already requested CloseAll,
  1.1124 + this request will be ignored.
  1.1125 + 
  1.1126 + @param	aMessage The reference to the message containing the client request: file lock.
  1.1127 + @leave KErrServerBusy if the requesting client is not the busy client. Plus other system-wide 
  1.1128 + errors.
  1.1129 + */
  1.1130 +EXPORT_C TCompletionType CBaServBackupSession::CloseAllFilesL(const RMessage2& aMessage)
  1.1131 +	{
  1.1132 +	// Raise file lock notifications
  1.1133 +	TRAPD(err,DoCloseAllFilesL(aMessage));
  1.1134 +	
  1.1135 +	if (err == KErrNone)
  1.1136 +		{
  1.1137 +		// Start timer to check all file locks re-registered before completing message
  1.1138 +		BackupServer()->StartCloseAllFilesOperationTimer(aMessage);
  1.1139 +		}
  1.1140 +	else
  1.1141 +		{
  1.1142 +		// If the error is that the same client has already requested CloseAll, ignore this request
  1.1143 +		// If not this error, recover the CloseAllOperationRunningState flag and leave with the error.
  1.1144 +		if (err != KErrAlreadyExists) 
  1.1145 +			{
  1.1146 +			BackupServer()->SetCloseAllOperationRunningState(EFalse);
  1.1147 +			User::Leave(err);
  1.1148 +			}
  1.1149 +		}
  1.1150 +
  1.1151 +	return ECompleteAsync;
  1.1152 +	}
  1.1153 +
  1.1154 +void CBaBackupServer::IncrementRegisteredFilesCount()
  1.1155 +	{
  1.1156 +	iRegisteredFilesCount++;
  1.1157 +	}
  1.1158 +
  1.1159 +void CBaBackupServer::DecrementRegisteredFilesCount(TInt aNumberFiles)
  1.1160 +	{
  1.1161 +	iRegisteredFilesCount = iRegisteredFilesCount - aNumberFiles;
  1.1162 +	}
  1.1163 +
  1.1164 +void CBaBackupServer::IncrementFilesReRegistrationCount()
  1.1165 +	{
  1.1166 +	iSessionLockReRegistrationCount++;
  1.1167 +	}
  1.1168 +
  1.1169 +/**
  1.1170 + Function called by both base and derived backup sessions in order to start asynchronous 
  1.1171 + file lock notifications.
  1.1172 + The requesting client is set to the current busy client.
  1.1173 + 
  1.1174 + @leave KErrServerBusy if the requesting client is not the current busy client or the server
  1.1175 + is under CloseAll operation. KErrAlreadyExists if the same client has sent CloseAll request.
  1.1176 + Plus other system-wide errors.
  1.1177 + */
  1.1178 + 
  1.1179 +EXPORT_C TCompletionType CBaServBackupSession::DoCloseAllFilesL(const RMessage2& /*aMessage*/)
  1.1180 +	{
  1.1181 +	CBaBackupServer* server=BackupServer();
  1.1182 +	if (server->IsOtherClientBusy(iUniqueClientId))
  1.1183 +		{
  1.1184 +		User::Leave(KErrServerBusy);
  1.1185 +		}
  1.1186 +		
  1.1187 +	if (BackupServer()->IsCloseAllOperationRunning())
  1.1188 +		{
  1.1189 +		User::Leave(KErrAlreadyExists);
  1.1190 +		}		
  1.1191 +		
  1.1192 +	CleanupStack::PushL(TCleanupItem(CleanupCloseAllFiles,this));
  1.1193 +	if (iClosedFiles)
  1.1194 +		{
  1.1195 +		delete iClosedFiles;
  1.1196 +		iClosedFiles=NULL;
  1.1197 +		}
  1.1198 +	server->SetBusy(iUniqueClientId);
  1.1199 +	
  1.1200 +	MBackupObserver::TFileLockFlags fileFlag=
  1.1201 +		(MBackupObserver::TFileLockFlags)iClientMessage->GetIntL(0);
  1.1202 +	server->CloseAllFilesL(fileFlag);
  1.1203 +	
  1.1204 +	iClosedFiles=new(ELeave) CArrayFixSeg<CBaServBackupSession::TClosedFile>(1);
  1.1205 +	CBaServBackupScheduler::Current()->SetErrorHandler(this);
  1.1206 +	CleanupStack::Pop(); // CleanupCloseAllFiles
  1.1207 +	return ECompleteAsync;
  1.1208 +	}
  1.1209 +
  1.1210 +/**
  1.1211 + *
  1.1212 + * Asks the server to signal all clients of getting the lock of their respective files.
  1.1213 + *
  1.1214 + */
  1.1215 +EXPORT_C void CBaServBackupSession::RestartAll()
  1.1216 +	{
  1.1217 +	CBaBackupServer* server=BackupServer();	
  1.1218 +	if (server->IsClientBusy(iUniqueClientId))
  1.1219 +		{
  1.1220 +		DoRestartAll();
  1.1221 +		}
  1.1222 +	}
  1.1223 +
  1.1224 +void CBaServBackupSession::DoRestartAll()
  1.1225 +	{
  1.1226 +	CBaBackupServer* server=BackupServer();	
  1.1227 +	server->RestartAll();
  1.1228 +	delete iReleasedFiles;
  1.1229 +	iReleasedFiles=NULL;
  1.1230 +	if (iClosedFiles)
  1.1231 +		{
  1.1232 +		CArrayFix<CBaServBackupSession::TClosedFile>* closedFiles=iClosedFiles;
  1.1233 +		iClosedFiles=NULL;
  1.1234 +		server->CompleteClosingFiles(closedFiles); // takes ownership of closedFiles immediately
  1.1235 +		}
  1.1236 +	}
  1.1237 +
  1.1238 +/**
  1.1239 +Handle the client's request to close a file.
  1.1240 +The request will be ignored if the requesting client the current busy client and the server is
  1.1241 +under CloseAll operation.
  1.1242 +
  1.1243 +@leave KErrServerBusy if the server is busy with the other client, plus other system-wide errors.
  1.1244 +*/
  1.1245 +void CBaServBackupSession::CloseFileL()
  1.1246 +	{
  1.1247 +	CBaBackupServer* server=BackupServer();
  1.1248 +	if (server->IsOtherClientBusy(iUniqueClientId))
  1.1249 +		{
  1.1250 +		User::Leave(KErrServerBusy);
  1.1251 +		}
  1.1252 +
  1.1253 +	if (! server->IsCloseAllOperationRunning())
  1.1254 +		{
  1.1255 +		MBackupObserver::TFileLockFlags flag=
  1.1256 +			static_cast<MBackupObserver::TFileLockFlags>(iClientMessage->GetIntL(2));
  1.1257 +		TFileName fileName;
  1.1258 +		GetFileNameL(fileName);
  1.1259 +		server->SetBusy(iUniqueClientId);
  1.1260 +		server->CloseFileL(flag,fileName);
  1.1261 +		}
  1.1262 +	}
  1.1263 +
  1.1264 +void CBaServBackupSession::RestartFileL()
  1.1265 +	{
  1.1266 +	TFileName fileName;
  1.1267 +	GetFileNameL(fileName);
  1.1268 +	BackupServer()->RestartFile(fileName);
  1.1269 +	}
  1.1270 +
  1.1271 +/**
  1.1272 +Handles the client's request of notification of a file lock change.
  1.1273 +  
  1.1274 +@leave KErrServerBusy if the server is under CloseAll operation, KLeaveWithoutAlert if the requested 
  1.1275 + file has been registered. Plus other system-wide errors.
  1.1276 +*/
  1.1277 +void CBaServBackupSession::NotifyLockChangeL()
  1.1278 +	{
  1.1279 +	if(BackupServer()->IsCloseAllOperationRunning())
  1.1280 +		{
  1.1281 +		User::Leave(KErrServerBusy);
  1.1282 +		}
  1.1283 +		
  1.1284 +	TFileName fileName;
  1.1285 +	GetFileNameL(fileName);
  1.1286 +	if (iFileLockObservers==NULL)
  1.1287 +		{
  1.1288 +		iFileLockObservers=new(ELeave) CDesCArraySeg(1);
  1.1289 +		}
  1.1290 +	else
  1.1291 +		{
  1.1292 +		TInt pos;
  1.1293 +		if(iFileLockObservers->Find(fileName,pos)== KErrNone)
  1.1294 +			{
  1.1295 +			iClientMessage->PanicClient(KPanic,EReqAlreadyOutstanding);
  1.1296 +			User::Leave(KLeaveWithoutAlert);
  1.1297 +			}		
  1.1298 +		}
  1.1299 +	iFileLockObservers->AppendL(fileName);
  1.1300 +	BackupServer()->IncrementRegisteredFilesCount();
  1.1301 +	}
  1.1302 +
  1.1303 +LOCAL_C void RemoveFileName(CDesCArray& aArray,const TDesC& aFileName)
  1.1304 +	{
  1.1305 +	TInt pos;
  1.1306 +	if (aArray.Find(aFileName,pos)==KErrNone)
  1.1307 +		{
  1.1308 +		aArray.Delete(pos);
  1.1309 +		}
  1.1310 +	}
  1.1311 +
  1.1312 +void CBaServBackupSession::NotifyLockChangeCancelL()
  1.1313 +	{
  1.1314 +	TFileName fileName;
  1.1315 +	GetFileNameL(fileName);
  1.1316 +	if (iFileLockObservers)
  1.1317 +		{
  1.1318 +		RemoveFileName(*iFileLockObservers,fileName);
  1.1319 +		BackupServer()->DecrementRegisteredFilesCount();
  1.1320 +		}
  1.1321 +	if (iReleasedFiles)
  1.1322 +		{
  1.1323 +		RemoveFileName(*iReleasedFiles,fileName);
  1.1324 +		}
  1.1325 +	iMessageQueue->RemoveItem(fileName);
  1.1326 +  	}
  1.1327 +
  1.1328 +void CBaServBackupSession::GetFileNameL(TDes& aFileName)
  1.1329 +	{
  1.1330 +	//The verification of this parameter has already been handled
  1.1331 +	//by the CClientMessage class so we can safely read the value
  1.1332 +	iClientMessage->ReadL(1,aFileName);
  1.1333 +	}
  1.1334 +
  1.1335 +
  1.1336 +void CBaServBackupSession::GetBackupOperationEventL(const RMessagePtr2& aPtr)
  1.1337 +	{
  1.1338 +	TPckg<TBackupOperationAttributes> backupOpAttPkg(iBackupOperationAttributes);
  1.1339 +	
  1.1340 +	aPtr.WriteL(0, backupOpAttPkg);
  1.1341 +	}
  1.1342 +
  1.1343 +void CBaServBackupSession::BackupOperationEventReadyL()
  1.1344 +	{
  1.1345 +	if (iBackupOperationObserverPresent)
  1.1346 +		{
  1.1347 +		iBackupOperationMessagePtr = iClientMessage->Message();
  1.1348 +		}
  1.1349 +	else
  1.1350 +		{
  1.1351 +		iClientMessage->CompleteRequestL(KErrNone);
  1.1352 +		}
  1.1353 +	}
  1.1354 +
  1.1355 +void CBaServBackupSession::NotifyBackupOperationL()
  1.1356 +	{
  1.1357 +	CBaBackupServer* server=BackupServer();
  1.1358 +	if (server->CBaBackupServer::IsOtherClientBusy(iUniqueClientId))
  1.1359 +		{
  1.1360 +		User::Leave(KErrServerBusy);
  1.1361 +		}
  1.1362 +	TPckg<TBackupOperationAttributes> backupOpAttPkg(iBackupOperationAttributes);
  1.1363 +	
  1.1364 +	iClientMessage->ReadL(0,backupOpAttPkg);
  1.1365 +
  1.1366 +	const TBool backupOperationRunning = ((iBackupOperationAttributes.iOperation==MBackupOperationObserver::EStart) ? ETrue : EFalse);
  1.1367 +	server->SetBackupOperationRunning(backupOperationRunning);
  1.1368 +	server->SetBusy(backupOperationRunning ? iUniqueClientId : 0);
  1.1369 +	server->SignalBackupOperation(iBackupOperationAttributes);
  1.1370 +	if (!iBackupOperationMessagePtr.IsNull())
  1.1371 +		{
  1.1372 +		GetBackupOperationEventL(iBackupOperationMessagePtr);
  1.1373 +		iBackupOperationMessagePtr.Complete(KErrCancel);
  1.1374 +		}
  1.1375 +	}
  1.1376 +
  1.1377 +void CBaServBackupSession::GetBackupOperationStateL()
  1.1378 +	{
  1.1379 +	const TBool isRunning = BackupServer()->IsBackupOperationRunning();
  1.1380 +	TPckgC<TBool> pkgObs(isRunning);
  1.1381 +
  1.1382 +	iClientMessage->WriteL(0, pkgObs);
  1.1383 +	}
  1.1384 +
  1.1385 +void CBaServBackupSession::SignalBackupOperation(const TBackupOperationAttributes& aBackupOperationAttributes)
  1.1386 +	{
  1.1387 +	iBackupOperationAttributes = aBackupOperationAttributes;
  1.1388 +	if (!iBackupOperationMessagePtr.IsNull())
  1.1389 +		{
  1.1390 +		TRAPD(err,GetBackupOperationEventL(iBackupOperationMessagePtr));
  1.1391 +		iBackupOperationMessagePtr.Complete(err);
  1.1392 +		}
  1.1393 +	}
  1.1394 +
  1.1395 +void CBaServBackupSession::StopNotifications()
  1.1396 +	{
  1.1397 +		if(!iNotificationPullMsg.IsNull())
  1.1398 +		{// complete the registration message
  1.1399 +		iNotificationPullMsg.Complete(KErrNone);
  1.1400 +		}
  1.1401 +	}
  1.1402 +
  1.1403 +/**
  1.1404 +@internalComponent
  1.1405 +*/
  1.1406 +CBaServBackupSession::CReRegistrationTimer* CBaServBackupSession::CReRegistrationTimer::NewL(TInt aPriority)
  1.1407 +	{ // static
  1.1408 +	CBaServBackupSession::CReRegistrationTimer* self=new(ELeave) CBaServBackupSession::CReRegistrationTimer(aPriority);
  1.1409 +	CleanupStack::PushL(self);
  1.1410 +	self->ConstructL();
  1.1411 +	CleanupStack::Pop(); // self
  1.1412 +	CActiveScheduler::Add(self);
  1.1413 +	return self;
  1.1414 +	}
  1.1415 +
  1.1416 +/**
  1.1417 +@internalComponent
  1.1418 +*/
  1.1419 +TInt CBaServBackupSession::CReRegistrationTimer::RunError(TInt aError)
  1.1420 +	{
  1.1421 +	if (aError==KLeaveWithoutAlert)
  1.1422 +		{
  1.1423 +		return KErrNone;
  1.1424 +		}
  1.1425 +	return aError;
  1.1426 +	}
  1.1427 +	
  1.1428 +/**
  1.1429 +@internalComponent
  1.1430 +*/
  1.1431 +CBaServBackupSession::CReRegistrationTimer::CReRegistrationTimer(TInt aPriority)
  1.1432 +	: CPeriodic(aPriority)
  1.1433 +	{ }
  1.1434 +	
  1.1435 +/**
  1.1436 +@internalComponent
  1.1437 +*/
  1.1438 +TInt CBaServBackupSession::CReRegistrationTimer::ReRegistrationTimerCallBack(TAny* aPtr)
  1.1439 +	{ // static
  1.1440 +	TRAP_IGNORE(REINTERPRET_CAST(CBaServBackupSession::CReRegistrationTimer*,aPtr)->HandleReRegistrationTimerCallBack());
  1.1441 +	return 0;
  1.1442 +	}
  1.1443 +
  1.1444 +/**
  1.1445 +@internalComponent
  1.1446 +*/
  1.1447 +void CBaServBackupSession::CReRegistrationTimer::HandleReRegistrationTimerCallBack()
  1.1448 +	{
  1.1449 +	iBackupServer->IncrementFilesReRegistrationCount();
  1.1450 +	
  1.1451 +	if (IsActive())
  1.1452 +		{
  1.1453 +		Cancel();
  1.1454 +		}
  1.1455 +	}
  1.1456 +