os/ossrv/lowlevellibsandfws/apputils/src/Baksrv.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <baksrv.h>
sl@0
    17
#include "Baksrvs.h"
sl@0
    18
#include <babackup.h>
sl@0
    19
#include <bafl/backup_std.h>
sl@0
    20
#include <basched.h>
sl@0
    21
#include <bsul/clientmessage.h>
sl@0
    22
#include "patchdata.h"
sl@0
    23
sl@0
    24
extern const BSUL::TClientMessageServerData KServerData;
sl@0
    25
sl@0
    26
const TInt KBakServMaxOperationTimerLoops = 3; // Number of iterations for base operation timer
sl@0
    27
sl@0
    28
_LIT(KPanic,"BackupServer");
sl@0
    29
//
sl@0
    30
// RMessage::Panic() also completes the message. This is:
sl@0
    31
// (a) important for efficient cleanup within the kernel
sl@0
    32
// (b) a problem if the message is completed a second time
sl@0
    33
//
sl@0
    34
void PanicClient(const RMessagePtr2& aMessage, TInt aPanic)
sl@0
    35
	{
sl@0
    36
	aMessage.Panic(KPanic,aPanic);
sl@0
    37
	}
sl@0
    38
sl@0
    39
sl@0
    40
//
sl@0
    41
// class CShutdownServer
sl@0
    42
//
sl@0
    43
sl@0
    44
NONSHARABLE_CLASS(CShutdownServer) : public CTimer
sl@0
    45
	{
sl@0
    46
	enum {KMyShutdownDelay=0x2000000};	// approx 2s
sl@0
    47
public:
sl@0
    48
	inline CShutdownServer();
sl@0
    49
	inline void ConstructL();
sl@0
    50
	inline void Start();
sl@0
    51
private:
sl@0
    52
	void RunL();
sl@0
    53
	};
sl@0
    54
sl@0
    55
inline CShutdownServer::CShutdownServer()
sl@0
    56
	:CTimer(-1)
sl@0
    57
	{
sl@0
    58
	CActiveScheduler::Add(this);
sl@0
    59
	}
sl@0
    60
sl@0
    61
inline void CShutdownServer::ConstructL()
sl@0
    62
	{
sl@0
    63
	CTimer::ConstructL();
sl@0
    64
	}
sl@0
    65
inline void CShutdownServer::Start()
sl@0
    66
	{
sl@0
    67
	After(KMyShutdownDelay);
sl@0
    68
	}
sl@0
    69
sl@0
    70
//
sl@0
    71
// Initiate server exit when the timer expires
sl@0
    72
//
sl@0
    73
void CShutdownServer::RunL()
sl@0
    74
	{
sl@0
    75
	CActiveScheduler::Stop();
sl@0
    76
	}
sl@0
    77
sl@0
    78
sl@0
    79
//
sl@0
    80
// class CBaServBackupScheduler
sl@0
    81
//
sl@0
    82
sl@0
    83
EXPORT_C CBaServBackupScheduler::CBaServBackupScheduler()
sl@0
    84
{
sl@0
    85
}
sl@0
    86
sl@0
    87
EXPORT_C CBaServBackupScheduler::~CBaServBackupScheduler()
sl@0
    88
{
sl@0
    89
}
sl@0
    90
sl@0
    91
/**
sl@0
    92
 *
sl@0
    93
 * Set the error handler to aErrorHandler to the current scheduler.
sl@0
    94
 *
sl@0
    95
 * @param     "CBaServBackupSession* aErrorHandler"
sl@0
    96
 *            The handler session.
sl@0
    97
 */
sl@0
    98
EXPORT_C void CBaServBackupScheduler::SetErrorHandler(CBaServBackupSession* aErrorHandler)
sl@0
    99
	{
sl@0
   100
	iErrorHandler=aErrorHandler;
sl@0
   101
	}
sl@0
   102
sl@0
   103
/**
sl@0
   104
 *
sl@0
   105
 * Handles the error aError.
sl@0
   106
 *
sl@0
   107
 * @param     "TInt aError"
sl@0
   108
 *            The error.
sl@0
   109
 */
sl@0
   110
EXPORT_C void CBaServBackupScheduler::Error(TInt aError) const
sl@0
   111
	{
sl@0
   112
	if (iErrorHandler)
sl@0
   113
		{
sl@0
   114
		iErrorHandler->HandleError(aError);
sl@0
   115
		}
sl@0
   116
	else if (aError!=KLeaveWithoutAlert)
sl@0
   117
		{
sl@0
   118
		// Handling the in this way implies that ServiceL should not leave.
sl@0
   119
		CActiveScheduler::Error(aError);
sl@0
   120
		}
sl@0
   121
	}
sl@0
   122
sl@0
   123
/**
sl@0
   124
Class CBaServBackupSession::CReRegistrationTimer
sl@0
   125
*/
sl@0
   126
NONSHARABLE_CLASS(CBaServBackupSession::CReRegistrationTimer) : public CPeriodic
sl@0
   127
{
sl@0
   128
	public:
sl@0
   129
		static CReRegistrationTimer* NewL(TInt aPriority);
sl@0
   130
		static TInt ReRegistrationTimerCallBack(TAny* aPtr);
sl@0
   131
		
sl@0
   132
	protected:
sl@0
   133
		TInt RunError(TInt aError);
sl@0
   134
		
sl@0
   135
	private:
sl@0
   136
		CReRegistrationTimer(TInt aPriority);
sl@0
   137
		void HandleReRegistrationTimerCallBack();
sl@0
   138
sl@0
   139
    public:
sl@0
   140
		CBaBackupServer* iBackupServer;
sl@0
   141
};
sl@0
   142
sl@0
   143
/**
sl@0
   144
Class CBaBackupServer::CBaServCloseAllOperationTimer
sl@0
   145
*/
sl@0
   146
sl@0
   147
NONSHARABLE_CLASS(CBaBackupServer::CBaServCloseAllOperationTimer): public CPeriodic
sl@0
   148
{
sl@0
   149
	public:
sl@0
   150
	    static CBaServCloseAllOperationTimer* NewL(CBaBackupServer* aBackupServer);
sl@0
   151
	   void ConstructL(CBaBackupServer* aBackupServer);
sl@0
   152
	   ~CBaServCloseAllOperationTimer();
sl@0
   153
	   void SetMessage(const RMessagePtr2& aPtr);
sl@0
   154
	   RMessagePtr2 Message();
sl@0
   155
	   TInt GetOperationCount();
sl@0
   156
	   void SetOperationCount(TInt aCount);
sl@0
   157
	   static TInt OperationTimerCallBack(TAny* aPtr);
sl@0
   158
	protected:
sl@0
   159
	   TInt RunError(TInt aError);
sl@0
   160
	private:
sl@0
   161
	   void HandleOperationTimerCallBack();
sl@0
   162
	   CBaServCloseAllOperationTimer();
sl@0
   163
	private:
sl@0
   164
	   RMessagePtr2 iCloseAllFilesMessage;
sl@0
   165
	   TInt16 iOperationCount;
sl@0
   166
	   CBaBackupServer* iBackupServer;
sl@0
   167
};
sl@0
   168
sl@0
   169
//
sl@0
   170
// class CBaBackupServer
sl@0
   171
//
sl@0
   172
sl@0
   173
/**
sl@0
   174
 *
sl@0
   175
 * Returns a pointer to <code>CBaBackupServer</code> object.
sl@0
   176
 *
sl@0
   177
 * @return   "CBaBackupServer"
sl@0
   178
 *            A newly-constructed backup server object.
sl@0
   179
 */
sl@0
   180
EXPORT_C CBaBackupServer* CBaBackupServer::NewL()
sl@0
   181
	{ // static
sl@0
   182
	CBaBackupServer* self=new(ELeave) CBaBackupServer(CActive::EPriorityStandard);
sl@0
   183
	return self;
sl@0
   184
	}
sl@0
   185
sl@0
   186
/**
sl@0
   187
 *
sl@0
   188
 * Constructor.
sl@0
   189
 *
sl@0
   190
 * @param     "TInt aPriority"
sl@0
   191
 *            The active object priority.
sl@0
   192
 */
sl@0
   193
EXPORT_C CBaBackupServer::CBaBackupServer(TInt aPriority)
sl@0
   194
	: CServer2(aPriority)
sl@0
   195
	{}
sl@0
   196
/**
sl@0
   197
 *
sl@0
   198
 * Destructor.
sl@0
   199
 *
sl@0
   200
 */
sl@0
   201
EXPORT_C CBaBackupServer::~CBaBackupServer()
sl@0
   202
	{
sl@0
   203
	TDblQueIter<CSession2> iter(iSessionIter);
sl@0
   204
	iter.SetToFirst();
sl@0
   205
sl@0
   206
	for (CSession2* session=iter++; session!=NULL; session=iter++)
sl@0
   207
		{
sl@0
   208
		delete session;
sl@0
   209
		}
sl@0
   210
	delete iShutdown;
sl@0
   211
	delete iExtension;
sl@0
   212
	delete iCloseAllFilesOperationTimer;
sl@0
   213
	}
sl@0
   214
sl@0
   215
/**
sl@0
   216
 *
sl@0
   217
 * Completes the server construction by adding the server to the active scheduler and creating
sl@0
   218
 * a <code>CShutdownServer</code> object.
sl@0
   219
 *
sl@0
   220
 */
sl@0
   221
EXPORT_C void CBaBackupServer::ConstructL()
sl@0
   222
	{
sl@0
   223
	StartL(__BACKUP_SERVER_NAME_V2);
sl@0
   224
	iExtension = new(ELeave) CBaBackupServerExt();
sl@0
   225
	iShutdown = new (ELeave) CShutdownServer;
sl@0
   226
	iShutdown->ConstructL();
sl@0
   227
	// ensure that the server still exits even if the 1st client fails to connect
sl@0
   228
	iShutdown->Start();
sl@0
   229
	iRegisteredFilesCount = 0;
sl@0
   230
	iCloseAllFilesOperationTimer = CBaBackupServer::CBaServCloseAllOperationTimer::NewL(this);
sl@0
   231
	iCloseAllOperationRunning = EFalse;
sl@0
   232
	
sl@0
   233
	//initialise the client message framework
sl@0
   234
	BSUL::CClientMessage::InitialiseFrameworkL(KServerData);
sl@0
   235
	}
sl@0
   236
sl@0
   237
/**
sl@0
   238
 *
sl@0
   239
 * Sets the server to be busy with the aUniqueClientId client.
sl@0
   240
 *
sl@0
   241
 * @param     "TUint32 aUniqueClientId"
sl@0
   242
 *            A unique client identifier.
sl@0
   243
 */
sl@0
   244
EXPORT_C void CBaBackupServer::SetBusy(TUint32 aUniqueClientId)
sl@0
   245
	{
sl@0
   246
	iExtension->iUniqueBusyClientId=aUniqueClientId;
sl@0
   247
	}
sl@0
   248
sl@0
   249
/**
sl@0
   250
 *
sl@0
   251
 * Returns <code>ETrue</code> if the client using the server is not the one identified by aUniqueClientId
sl@0
   252
 * oterwise <code>EFalse</code>
sl@0
   253
 *
sl@0
   254
 * @param     "TUint32 aUniqueClientId"
sl@0
   255
 *            A unique client identifier.
sl@0
   256
 */
sl@0
   257
EXPORT_C TBool CBaBackupServer::IsOtherClientBusy(TUint32 aUniqueClientId) const
sl@0
   258
	{
sl@0
   259
	return (iExtension->iUniqueBusyClientId!=0 && iExtension->iUniqueBusyClientId!=aUniqueClientId);
sl@0
   260
	}
sl@0
   261
sl@0
   262
/**
sl@0
   263
 *
sl@0
   264
 * Returns <code>ETrue</code> if the client using the server corresponds has aUniqueClientId as unique id
sl@0
   265
 * oterwise <code>EFalse</code>
sl@0
   266
 *
sl@0
   267
 * @param     "TUint32 aUniqueClientId"
sl@0
   268
 *            A unique client identifier id.
sl@0
   269
 */
sl@0
   270
EXPORT_C TBool CBaBackupServer::IsClientBusy(TUint32 aUniqueClientId) const
sl@0
   271
	{
sl@0
   272
	return ((iExtension->iUniqueBusyClientId==aUniqueClientId) || 
sl@0
   273
			((iExtension->iCachedBusyClientId != 0) && (iExtension->iCachedBusyClientId == aUniqueClientId))); 
sl@0
   274
	}
sl@0
   275
sl@0
   276
/**
sl@0
   277
 *
sl@0
   278
 * Handles the closing of all files by signaling the new file lock flag, aFlag, to all client.
sl@0
   279
 *
sl@0
   280
 * @param     "MBackupObserver::TFileLockFlags aFlag"
sl@0
   281
 *            A file lock flag.
sl@0
   282
 */
sl@0
   283
EXPORT_C void CBaBackupServer::CloseAllFilesL(MBackupObserver::TFileLockFlags aFlag)
sl@0
   284
	{
sl@0
   285
	// Set the close all operation flag and the reregistration counter to zero
sl@0
   286
	iCloseAllOperationRunning = ETrue;
sl@0
   287
	iSessionLockReRegistrationCount = 0;
sl@0
   288
	
sl@0
   289
	// cleanup that calls RestartAll if required
sl@0
   290
	TDblQueIter<CSession2> iter(iSessionIter);
sl@0
   291
	iter.SetToFirst();
sl@0
   292
sl@0
   293
	for (CSession2* session=iter++; session!=NULL; session=iter++)
sl@0
   294
		{
sl@0
   295
		static_cast<CBaServBackupSession*>(session)->SignalReleaseAllFileLocksL(aFlag);
sl@0
   296
		}
sl@0
   297
	}
sl@0
   298
sl@0
   299
/**
sl@0
   300
 *
sl@0
   301
 * Signals to all clients of getting the lock of their respective files.
sl@0
   302
 *
sl@0
   303
 */
sl@0
   304
EXPORT_C void CBaBackupServer::RestartAll()
sl@0
   305
	{
sl@0
   306
	TDblQueIter<CSession2> iter(iSessionIter);
sl@0
   307
	iter.SetToFirst();
sl@0
   308
sl@0
   309
	for (CSession2* session=iter++; session!=NULL; session=iter++)
sl@0
   310
		{
sl@0
   311
		static_cast<CBaServBackupSession*>(session)->SignalRetakeAllFileLocks();
sl@0
   312
		}
sl@0
   313
	}
sl@0
   314
sl@0
   315
/**
sl@0
   316
 *
sl@0
   317
 * Allows any subclass of <code>CBaBackupServer</code> of completing the closing of files.
sl@0
   318
 * The server will lose the ownership of aClosedFiles object, which implies it is up to this virtual
sl@0
   319
 * function to deal with it in order to avoid a memory leak.
sl@0
   320
 *
sl@0
   321
 * @param     "CArrayFix<CBaServBackupSession::TClosedFile>* aClosedFiles"
sl@0
   322
 *            An array of closed files.
sl@0
   323
 */
sl@0
   324
EXPORT_C void CBaBackupServer::CompleteClosingFiles(CArrayFix<CBaServBackupSession::TClosedFile>* aClosedFiles)
sl@0
   325
	{
sl@0
   326
	delete aClosedFiles;
sl@0
   327
	}
sl@0
   328
sl@0
   329
/**
sl@0
   330
 *
sl@0
   331
 * Allows application framework backup code to check if all registerd files have beem updated
sl@0
   332
 *
sl@0
   333
 */
sl@0
   334
EXPORT_C TBool CBaBackupServer::HaveAllCloseAllFilesClientsReRegistered()
sl@0
   335
	{
sl@0
   336
	return((iRegisteredFilesCount == iSessionLockReRegistrationCount) ? ETrue : EFalse);
sl@0
   337
	}
sl@0
   338
sl@0
   339
void CBaBackupServer::CloseFileL(MBackupObserver::TFileLockFlags aFlag,const TDesC& aFileName)
sl@0
   340
	{
sl@0
   341
	TDblQueIter<CSession2> iter(iSessionIter);
sl@0
   342
	iter.SetToFirst();
sl@0
   343
sl@0
   344
	for (CSession2* session=iter++; session!=NULL; session=iter++)
sl@0
   345
		{
sl@0
   346
		static_cast<CBaServBackupSession*>(session)->SignalReleaseFileLockL(aFlag,aFileName);
sl@0
   347
		}
sl@0
   348
	}
sl@0
   349
sl@0
   350
void CBaBackupServer::RestartFile(const TDesC& aFileName)
sl@0
   351
	{
sl@0
   352
	TDblQueIter<CSession2> iter(iSessionIter);
sl@0
   353
	iter.SetToFirst();
sl@0
   354
sl@0
   355
	for (CSession2* session=iter++; session!=NULL; session=iter++)
sl@0
   356
		{
sl@0
   357
		static_cast<CBaServBackupSession*>(session)->SignalRetakeFileLocks(aFileName);
sl@0
   358
		}
sl@0
   359
	}
sl@0
   360
sl@0
   361
/**
sl@0
   362
 *
sl@0
   363
 * Creates a server-side client <code>CBaServBackupSession</code> session object by checking first if
sl@0
   364
 * the version of the server is compatible with the client.
sl@0
   365
 *
sl@0
   366
 * @param     "const TVersion &aVersion"
sl@0
   367
 *            Version information supplied by the client.
sl@0
   368
 */
sl@0
   369
EXPORT_C CSession2* CBaBackupServer::NewSessionL(const TVersion &aVersion, const RMessage2& /*aMessage*/) const
sl@0
   370
	{
sl@0
   371
	TVersion ver(KBakServMajorVN,KBakServMinorVN,KBakServBuildVN);
sl@0
   372
	if (!User::QueryVersionSupported(ver,aVersion))
sl@0
   373
		User::Leave(KErrNotSupported);
sl@0
   374
//
sl@0
   375
	return CBaServBackupSession::NewL();
sl@0
   376
	}
sl@0
   377
sl@0
   378
/**
sl@0
   379
 *
sl@0
   380
 * Signals to all clients the aBackupOperationAttributes.
sl@0
   381
 *
sl@0
   382
 * @param     "const TBackupOperationAttributes& aBackupOperationAttributes"
sl@0
   383
 *            Backup operation attributes.
sl@0
   384
 */
sl@0
   385
EXPORT_C void CBaBackupServer::SignalBackupOperation(const TBackupOperationAttributes& aBackupOperationAttributes)
sl@0
   386
	{
sl@0
   387
	TDblQueIter<CSession2> iter(iSessionIter);
sl@0
   388
	iter.SetToFirst();
sl@0
   389
sl@0
   390
	for (CSession2* session=iter++; session!=NULL; session=iter++)
sl@0
   391
		{
sl@0
   392
		static_cast<CBaServBackupSession*>(session)->SignalBackupOperation(aBackupOperationAttributes);
sl@0
   393
		}
sl@0
   394
	// Cache session id if starting backup
sl@0
   395
	if (aBackupOperationAttributes.iOperation == MBackupOperationObserver::EStart)
sl@0
   396
			iExtension->iCachedBusyClientId = iExtension->iUniqueBusyClientId;
sl@0
   397
	}
sl@0
   398
sl@0
   399
void CBaBackupServer::AddSession()
sl@0
   400
	{
sl@0
   401
	iShutdown->Cancel();
sl@0
   402
	++iSessionCount;
sl@0
   403
	}
sl@0
   404
sl@0
   405
void CBaBackupServer::DropSession()
sl@0
   406
	{
sl@0
   407
	if (--iSessionCount==0)
sl@0
   408
		{
sl@0
   409
		iShutdown->Start();
sl@0
   410
		}
sl@0
   411
	}
sl@0
   412
sl@0
   413
/*
sl@0
   414
 * Check to see if a CloseAll opertation is in progress
sl@0
   415
 * 
sl@0
   416
 */
sl@0
   417
TBool CBaBackupServer::IsCloseAllOperationRunning()
sl@0
   418
	{
sl@0
   419
	return iCloseAllOperationRunning;
sl@0
   420
	}
sl@0
   421
sl@0
   422
/*
sl@0
   423
 * Set value of IsCloseAllOperationRunning
sl@0
   424
 * 
sl@0
   425
 */
sl@0
   426
EXPORT_C void CBaBackupServer::SetCloseAllOperationRunningState(TBool aRunning)
sl@0
   427
	{
sl@0
   428
	iCloseAllOperationRunning = aRunning;
sl@0
   429
	}
sl@0
   430
sl@0
   431
/**
sl@0
   432
 *
sl@0
   433
 * This timer will only be created in cases of no derived backup server
sl@0
   434
 *
sl@0
   435
 */
sl@0
   436
void CBaBackupServer::StartCloseAllFilesOperationTimer(const RMessagePtr2& aPtr)
sl@0
   437
	{
sl@0
   438
	// Store the CloseAll message in case we need to Complete on a timeout
sl@0
   439
	iCloseAllFilesOperationTimer->SetMessage(aPtr);
sl@0
   440
	
sl@0
   441
	// If hardware use patchable constant if not default to 3 seconds
sl@0
   442
	iCloseAllFilesOperationTimer->Start(KBaBackupCloseallFilesTimeout, KBaBackupCloseallFilesTimeout, TCallBack(CBaBackupServer::CBaServCloseAllOperationTimer::OperationTimerCallBack, iCloseAllFilesOperationTimer));
sl@0
   443
	}
sl@0
   444
sl@0
   445
/**
sl@0
   446
 * Handle an error from CBaServBackupSession::ServiceL()
sl@0
   447
 * A bad descriptor error implies a badly programmed client, so panic it;
sl@0
   448
 * otherwise report the error to the client
sl@0
   449
 *
sl@0
   450
 * @param     "TInt aError"
sl@0
   451
 *            The error.
sl@0
   452
 */
sl@0
   453
EXPORT_C TInt CBaBackupServer::RunError(TInt aError)
sl@0
   454
	{
sl@0
   455
	if (aError==KErrBadDescriptor)
sl@0
   456
		{
sl@0
   457
		PanicClient(Message(), EBufferOverflow);
sl@0
   458
		}
sl@0
   459
	else
sl@0
   460
		{
sl@0
   461
		Message().Complete(aError);
sl@0
   462
		}
sl@0
   463
	//
sl@0
   464
	// The leave will result in an early return from CServer::RunL(), skipping
sl@0
   465
	// the call to request another message. So do that now in order to keep the
sl@0
   466
	// server running.
sl@0
   467
	ReStart();
sl@0
   468
	return KErrNone;	// handled the error fully
sl@0
   469
	}
sl@0
   470
sl@0
   471
//
sl@0
   472
// class CBaBackupServer::CBaServCloseAllOperationTimer
sl@0
   473
//
sl@0
   474
sl@0
   475
/**
sl@0
   476
@internalComponent
sl@0
   477
*/
sl@0
   478
CBaBackupServer::CBaServCloseAllOperationTimer* CBaBackupServer::CBaServCloseAllOperationTimer::NewL(CBaBackupServer* aBackupServer)
sl@0
   479
	{ // static
sl@0
   480
	CBaBackupServer::CBaServCloseAllOperationTimer* self=new(ELeave) CBaBackupServer::CBaServCloseAllOperationTimer();
sl@0
   481
	CleanupStack::PushL(self);
sl@0
   482
	self->ConstructL(aBackupServer);
sl@0
   483
	CleanupStack::Pop(); // self
sl@0
   484
	CActiveScheduler::Add(self);
sl@0
   485
	return self;
sl@0
   486
	}
sl@0
   487
sl@0
   488
/**
sl@0
   489
@internalComponent
sl@0
   490
*/
sl@0
   491
sl@0
   492
void CBaBackupServer::CBaServCloseAllOperationTimer::ConstructL(CBaBackupServer* aBackupServer)
sl@0
   493
	{
sl@0
   494
	CTimer::ConstructL();
sl@0
   495
	iBackupServer = aBackupServer;
sl@0
   496
	iOperationCount = 0;
sl@0
   497
	}
sl@0
   498
/**
sl@0
   499
@internalComponent
sl@0
   500
*/
sl@0
   501
sl@0
   502
TInt CBaBackupServer::CBaServCloseAllOperationTimer::GetOperationCount()
sl@0
   503
{
sl@0
   504
	return iOperationCount;	
sl@0
   505
}
sl@0
   506
sl@0
   507
/**
sl@0
   508
@internalComponent
sl@0
   509
*/
sl@0
   510
sl@0
   511
void CBaBackupServer::CBaServCloseAllOperationTimer::SetOperationCount(TInt aCount)
sl@0
   512
{
sl@0
   513
	iOperationCount = aCount;
sl@0
   514
}
sl@0
   515
sl@0
   516
/**
sl@0
   517
@internalComponent
sl@0
   518
*/
sl@0
   519
sl@0
   520
TInt CBaBackupServer::CBaServCloseAllOperationTimer::RunError(TInt aError)
sl@0
   521
	{
sl@0
   522
	if (aError==KLeaveWithoutAlert)
sl@0
   523
		{
sl@0
   524
		return KErrNone;
sl@0
   525
		}
sl@0
   526
	return aError;
sl@0
   527
	}
sl@0
   528
	
sl@0
   529
/**
sl@0
   530
@internalComponent
sl@0
   531
*/
sl@0
   532
CBaBackupServer::CBaServCloseAllOperationTimer::CBaServCloseAllOperationTimer()
sl@0
   533
	: CPeriodic(CActive::EPriorityStandard)
sl@0
   534
	{ ;	}
sl@0
   535
	
sl@0
   536
/**
sl@0
   537
@internalComponent
sl@0
   538
*/
sl@0
   539
CBaBackupServer::CBaServCloseAllOperationTimer::~CBaServCloseAllOperationTimer()
sl@0
   540
	{
sl@0
   541
	if (IsActive())
sl@0
   542
		Cancel();	
sl@0
   543
	}
sl@0
   544
sl@0
   545
/**
sl@0
   546
@internalComponent
sl@0
   547
*/
sl@0
   548
void CBaBackupServer::CBaServCloseAllOperationTimer::SetMessage(const RMessagePtr2& aPtr)
sl@0
   549
	{
sl@0
   550
	iCloseAllFilesMessage = aPtr;
sl@0
   551
	}
sl@0
   552
sl@0
   553
/**
sl@0
   554
@internalComponent
sl@0
   555
*/
sl@0
   556
RMessagePtr2 CBaBackupServer::CBaServCloseAllOperationTimer::Message()
sl@0
   557
	{
sl@0
   558
	return iCloseAllFilesMessage;
sl@0
   559
	}
sl@0
   560
	
sl@0
   561
/**
sl@0
   562
@internalComponent
sl@0
   563
*/
sl@0
   564
TInt CBaBackupServer::CBaServCloseAllOperationTimer::OperationTimerCallBack(TAny* aPtr)
sl@0
   565
	{ // static
sl@0
   566
	TRAP_IGNORE(REINTERPRET_CAST(CBaBackupServer::CBaServCloseAllOperationTimer*,aPtr)->HandleOperationTimerCallBack());
sl@0
   567
	return 0;
sl@0
   568
	}
sl@0
   569
sl@0
   570
/**
sl@0
   571
@internalComponent
sl@0
   572
*/
sl@0
   573
void CBaBackupServer::CBaServCloseAllOperationTimer::HandleOperationTimerCallBack()
sl@0
   574
	{
sl@0
   575
	TBool finished = iBackupServer->HaveAllCloseAllFilesClientsReRegistered();
sl@0
   576
	TInt retCode;
sl@0
   577
	if (finished || (iOperationCount == KBakServMaxOperationTimerLoops))
sl@0
   578
		{
sl@0
   579
		if (finished)
sl@0
   580
			{
sl@0
   581
			retCode = KErrNone;
sl@0
   582
			}
sl@0
   583
		else
sl@0
   584
			{
sl@0
   585
			retCode = KErrLocked;
sl@0
   586
			}
sl@0
   587
		
sl@0
   588
		// One way or another CloseAll is finished at this point
sl@0
   589
		iBackupServer->SetCloseAllOperationRunningState(EFalse);
sl@0
   590
		
sl@0
   591
		iCloseAllFilesMessage.Complete(retCode);
sl@0
   592
		Cancel();
sl@0
   593
		}
sl@0
   594
	else
sl@0
   595
		{
sl@0
   596
		iOperationCount++;
sl@0
   597
		if (IsActive())
sl@0
   598
			{
sl@0
   599
			Cancel();
sl@0
   600
sl@0
   601
			// If hardware use patchable constant if not default to 3 seconds
sl@0
   602
			Start(KBaBackupCloseallFilesTimeout, KBaBackupCloseallFilesTimeout, TCallBack(CBaBackupServer::CBaServCloseAllOperationTimer::OperationTimerCallBack,this));
sl@0
   603
			}
sl@0
   604
		}
sl@0
   605
	}
sl@0
   606
sl@0
   607
//
sl@0
   608
// class CBaServBackupMessageQueue
sl@0
   609
//
sl@0
   610
sl@0
   611
inline CBaServBackupMessageQueue::TQueueItem::TQueueItem(HBufC* aFileName,TInt aOperation)
sl@0
   612
	: iFileName(aFileName), iOperation(aOperation)
sl@0
   613
	{}
sl@0
   614
sl@0
   615
CBaServBackupMessageQueue* CBaServBackupMessageQueue::NewL()
sl@0
   616
	{ // static
sl@0
   617
	CBaServBackupMessageQueue* self=new(ELeave) CBaServBackupMessageQueue();
sl@0
   618
	return self;
sl@0
   619
	}
sl@0
   620
sl@0
   621
CBaServBackupMessageQueue::~CBaServBackupMessageQueue()
sl@0
   622
	{
sl@0
   623
	const TInt count=iQueue.Count();
sl@0
   624
	for (TInt ii=0;ii<count;ii++)
sl@0
   625
		{
sl@0
   626
		delete iQueue[ii].iFileName;
sl@0
   627
		}
sl@0
   628
	iQueue.Reset();
sl@0
   629
	iQueue.Close();
sl@0
   630
	}
sl@0
   631
sl@0
   632
void CBaServBackupMessageQueue::AddItemL(const TDesC& aFileName,MBackupObserver::TFileLockFlags aFlag)
sl@0
   633
	{
sl@0
   634
	const TInt count=iQueue.Count();
sl@0
   635
	for (TInt ii=0;ii<count;ii++)
sl@0
   636
		{
sl@0
   637
		TQueueItem& item=iQueue[ii];
sl@0
   638
		if(aFileName.MatchF(*item.iFileName) == KErrNone)
sl@0
   639
			{
sl@0
   640
			if (item.iOperation==MBackupObserver::EReleaseLockReadOnly && aFlag==MBackupObserver::EReleaseLockNoAccess)
sl@0
   641
				{
sl@0
   642
				item.iOperation=MBackupObserver::EReleaseLockNoAccess;
sl@0
   643
				}
sl@0
   644
			else if (item.iOperation!=MBackupObserver::EReleaseLockNoAccess)
sl@0
   645
				{
sl@0
   646
				HBufC* file=aFileName.AllocLC();
sl@0
   647
				TQueueItem item(file,aFlag);
sl@0
   648
				User::LeaveIfError(iQueue.Insert(item,ii));
sl@0
   649
				CleanupStack::Pop(); // file
sl@0
   650
				}
sl@0
   651
			return;
sl@0
   652
			}
sl@0
   653
		}
sl@0
   654
	HBufC* file=aFileName.AllocLC();
sl@0
   655
	HBufC* copy=aFileName.AllocLC();
sl@0
   656
	TQueueItem item(file,aFlag);
sl@0
   657
	User::LeaveIfError(iQueue.Append(item));
sl@0
   658
	item=TQueueItem(copy,-1);
sl@0
   659
	const TInt err=iQueue.Append(item);
sl@0
   660
	if (err!=KErrNone)
sl@0
   661
		{
sl@0
   662
		iQueue.Remove(iQueue.Count()-1);
sl@0
   663
		User::Leave(err);
sl@0
   664
		}
sl@0
   665
	CleanupStack::Pop(2); // copy, file
sl@0
   666
	}
sl@0
   667
sl@0
   668
void CBaServBackupMessageQueue::AddItem(const TDesC& aFileName)
sl@0
   669
	{
sl@0
   670
	const TInt count=iQueue.Count();
sl@0
   671
	for (TInt ii=0;ii<count;ii++)
sl@0
   672
		{
sl@0
   673
		TQueueItem& item=iQueue[ii];
sl@0
   674
		if (aFileName.MatchF(*item.iFileName) == KErrNone && item.iOperation==-1)
sl@0
   675
			{
sl@0
   676
			item.iOperation=0;
sl@0
   677
			break;
sl@0
   678
			}
sl@0
   679
		}
sl@0
   680
	}
sl@0
   681
sl@0
   682
TBool CBaServBackupMessageQueue::IsEmpty() const
sl@0
   683
	{
sl@0
   684
	return HeadIndex()==KErrNotFound;
sl@0
   685
	}
sl@0
   686
sl@0
   687
void CBaServBackupMessageQueue::RemoveHead()
sl@0
   688
	{
sl@0
   689
	const TInt index=HeadIndex();
sl@0
   690
	if (index!=KErrNotFound)
sl@0
   691
		{
sl@0
   692
		delete iQueue[index].iFileName;
sl@0
   693
		iQueue.Remove(index);
sl@0
   694
		iQueue.Compress();
sl@0
   695
		}
sl@0
   696
	}
sl@0
   697
sl@0
   698
void CBaServBackupMessageQueue::RemoveItem(const TDesC& aFileName)
sl@0
   699
	{
sl@0
   700
	const TInt count=iQueue.Count();
sl@0
   701
	for (TInt ii=count-1;ii>=0;ii--)
sl@0
   702
		{
sl@0
   703
		const TQueueItem& item=iQueue[ii];
sl@0
   704
		if (aFileName.MatchF(*item.iFileName) == KErrNone)
sl@0
   705
			{
sl@0
   706
			delete item.iFileName;
sl@0
   707
			iQueue.Remove(ii);
sl@0
   708
			iQueue.Compress();
sl@0
   709
			}
sl@0
   710
		}
sl@0
   711
	}
sl@0
   712
sl@0
   713
void CBaServBackupMessageQueue::GetHead(TDes& aFileName,MBackupObserver::TFileLockFlags& aFlag) const
sl@0
   714
	{
sl@0
   715
	aFileName.Zero();
sl@0
   716
	const TInt index=HeadIndex();
sl@0
   717
	if (index!=KErrNotFound)
sl@0
   718
		{
sl@0
   719
		const TQueueItem& item=iQueue[index];
sl@0
   720
		aFileName=item.iFileName->Des();
sl@0
   721
		aFlag=(MBackupObserver::TFileLockFlags)item.iOperation;
sl@0
   722
		}
sl@0
   723
	}
sl@0
   724
sl@0
   725
TInt CBaServBackupMessageQueue::HeadIndex() const
sl@0
   726
	{
sl@0
   727
	TInt index=KErrNotFound;
sl@0
   728
	const TInt count=iQueue.Count();
sl@0
   729
	for (TInt ii=0;ii<count;ii++)
sl@0
   730
		{
sl@0
   731
		const TQueueItem& item=iQueue[ii];
sl@0
   732
		if (item.iOperation!=ENoOp)
sl@0
   733
			{
sl@0
   734
			index=ii;
sl@0
   735
			break;
sl@0
   736
			}
sl@0
   737
		}
sl@0
   738
	return index;
sl@0
   739
	}
sl@0
   740
sl@0
   741
//
sl@0
   742
// class CBaServBackupSession
sl@0
   743
//
sl@0
   744
sl@0
   745
CBaServBackupSession* CBaServBackupSession::NewL()
sl@0
   746
	{ // static
sl@0
   747
	CBaServBackupSession* self=new(ELeave) CBaServBackupSession();
sl@0
   748
	CleanupStack::PushL(self);
sl@0
   749
	self->ConstructL();
sl@0
   750
	CleanupStack::Pop(); // self
sl@0
   751
	return self;
sl@0
   752
	}
sl@0
   753
sl@0
   754
/**
sl@0
   755
 *
sl@0
   756
 * Constructor.
sl@0
   757
 *
sl@0
   758
 * @param     "RThread aClient"
sl@0
   759
 *            The client thread for which this server-side client session is being constructed.
sl@0
   760
 */
sl@0
   761
EXPORT_C CBaServBackupSession::CBaServBackupSession()
sl@0
   762
	: CSession2()
sl@0
   763
	{
sl@0
   764
	iUniqueClientId = (TUint32)this;
sl@0
   765
	}
sl@0
   766
sl@0
   767
/**
sl@0
   768
 *
sl@0
   769
 * Destructor.
sl@0
   770
 *
sl@0
   771
 */
sl@0
   772
EXPORT_C CBaServBackupSession::~CBaServBackupSession()
sl@0
   773
	{
sl@0
   774
	CBaBackupServer* server=BackupServer();
sl@0
   775
	if (server->IsClientBusy(iUniqueClientId))
sl@0
   776
		{
sl@0
   777
		RestartAll();
sl@0
   778
		if (server->IsBackupOperationRunning())
sl@0
   779
			{
sl@0
   780
			TBackupOperationAttributes backupOpAtt(MBackupObserver::ETakeLock, MBackupOperationObserver::EAbort);
sl@0
   781
			server->SignalBackupOperation(backupOpAtt);
sl@0
   782
			server->SetBackupOperationRunning(EFalse);
sl@0
   783
			}
sl@0
   784
		server->SetBusy(0);
sl@0
   785
		}
sl@0
   786
sl@0
   787
	if (iFileLockObservers)
sl@0
   788
		{
sl@0
   789
		server->DecrementRegisteredFilesCount(iFileLockObservers->Count());	
sl@0
   790
		}
sl@0
   791
sl@0
   792
	delete iClosedFiles;
sl@0
   793
	delete iFileLockObservers;
sl@0
   794
	delete iReleasedFiles;
sl@0
   795
	delete iMessageQueue;
sl@0
   796
	delete iReRegistrationTimer;
sl@0
   797
	iReRegistrationTimer = 0;
sl@0
   798
	server->DropSession();
sl@0
   799
	}
sl@0
   800
sl@0
   801
/**
sl@0
   802
 *
sl@0
   803
 * Completes the session construction by creating a <code>CBaServBackupMessageQueue</code> object.
sl@0
   804
 *
sl@0
   805
 */
sl@0
   806
EXPORT_C void CBaServBackupSession::ConstructL()
sl@0
   807
	{
sl@0
   808
	iMessageQueue=CBaServBackupMessageQueue::NewL();
sl@0
   809
sl@0
   810
	// Cannot set iBackupServer in CReRegistrationTimer at this point but must be done before call to Start
sl@0
   811
	iReRegistrationTimer=CBaServBackupSession::CReRegistrationTimer::NewL(CActive::EPriorityStandard);
sl@0
   812
	}
sl@0
   813
sl@0
   814
/**
sl@0
   815
 *
sl@0
   816
 * Completes the construction of this <code>CBaServBackupSession</code> session by just doing a base call class.
sl@0
   817
 * It also notify the server that a new session has been created.
sl@0
   818
 *
sl@0
   819
 * @param		"const CServer& aServer"
sl@0
   820
 *				The server active object which is responsible for this session
sl@0
   821
 */
sl@0
   822
EXPORT_C void CBaServBackupSession::CreateL()
sl@0
   823
	{
sl@0
   824
	BackupServer()->AddSession();
sl@0
   825
	}
sl@0
   826
sl@0
   827
void CBaServBackupSession::SignalReleaseAllFileLocksL(MBackupObserver::TFileLockFlags aFlag)
sl@0
   828
	{
sl@0
   829
	CBaBackupServer* server=BackupServer();
sl@0
   830
	if (iFileLockObservers)
sl@0
   831
		{
sl@0
   832
		const TInt count=iFileLockObservers->Count();
sl@0
   833
		for (TInt ii=0;ii<count;ii++)
sl@0
   834
			{
sl@0
   835
			TFileName name=(*iFileLockObservers)[ii];
sl@0
   836
			server->CloseFileL(aFlag,name);
sl@0
   837
			}
sl@0
   838
		}
sl@0
   839
	}
sl@0
   840
sl@0
   841
void CBaServBackupSession::SignalRetakeAllFileLocks()
sl@0
   842
	{
sl@0
   843
//	CBaBackupServer* server=BackupServer();
sl@0
   844
	if (iReleasedFiles)
sl@0
   845
		{
sl@0
   846
		const TInt count=iReleasedFiles->Count();
sl@0
   847
		for (TInt ii=count-1;ii>=0;ii--)
sl@0
   848
			{
sl@0
   849
			TFileName name=(*iReleasedFiles)[ii];
sl@0
   850
//			server->RestartFile(name);
sl@0
   851
			SignalRetakeFileLocks(name);
sl@0
   852
			}
sl@0
   853
		}
sl@0
   854
	}
sl@0
   855
sl@0
   856
LOCAL_C void CleanupCloseFail(TAny* aPtr)
sl@0
   857
	{
sl@0
   858
	CDesCArray* array=REINTERPRET_CAST(CDesCArray*,aPtr);
sl@0
   859
	array->Delete(array->Count()-1);
sl@0
   860
	}
sl@0
   861
sl@0
   862
void CBaServBackupSession::SignalReleaseFileLockL(MBackupObserver::TFileLockFlags aFlag,const TDesC& aFileName)
sl@0
   863
	{
sl@0
   864
	TInt pos;
sl@0
   865
	if (iFileLockObservers && iFileLockObservers->Find(aFileName,pos)==KErrNone)
sl@0
   866
		{
sl@0
   867
		if (iReleasedFiles==NULL)
sl@0
   868
			{
sl@0
   869
			iReleasedFiles=new(ELeave) CDesCArraySeg(1);
sl@0
   870
			}
sl@0
   871
		const TBool addedReleasedFile=iReleasedFiles->Find(aFileName,pos)!=KErrNone;
sl@0
   872
		if (addedReleasedFile)
sl@0
   873
			{
sl@0
   874
			iReleasedFiles->AppendL(aFileName);
sl@0
   875
			CleanupStack::PushL(TCleanupItem(CleanupCloseFail,iReleasedFiles));
sl@0
   876
			}
sl@0
   877
		iMessageQueue->AddItemL(aFileName,aFlag);
sl@0
   878
		if (!iNotificationPullMsg.IsNull())
sl@0
   879
  			{
sl@0
   880
  			iNotificationPullMsg.Complete(KErrNone);
sl@0
   881
sl@0
   882
  			// Okay - if this is part of a CloseAll operation we need to kick off a ReRegistration timer
sl@0
   883
  			if (BackupServer()->IsCloseAllOperationRunning())
sl@0
   884
  				{
sl@0
   885
  				// Set backup server for the timer
sl@0
   886
  				iReRegistrationTimer->iBackupServer = BackupServer();
sl@0
   887
sl@0
   888
  				// If hardware use patchable constant if not default to 3 seconds
sl@0
   889
  				iReRegistrationTimer->Start(KBaBackupFileLockReRegistrationTimeout, KBaBackupFileLockReRegistrationTimeout, TCallBack(CBaServBackupSession::CReRegistrationTimer::ReRegistrationTimerCallBack, iReRegistrationTimer));  				
sl@0
   890
  				}
sl@0
   891
sl@0
   892
  			}
sl@0
   893
		if (addedReleasedFile)
sl@0
   894
			{
sl@0
   895
			CleanupStack::Pop(); // CleanupCloseFail
sl@0
   896
			}
sl@0
   897
		}
sl@0
   898
	}
sl@0
   899
sl@0
   900
void CBaServBackupSession::SignalRetakeFileLocks(const TDesC& aFileName)
sl@0
   901
	{
sl@0
   902
	if (iReleasedFiles)
sl@0
   903
		{
sl@0
   904
		const TInt count=iReleasedFiles->Count();
sl@0
   905
		for (TInt ii=count-1;ii>=0;ii--)
sl@0
   906
			{
sl@0
   907
			TFileName name=(*iReleasedFiles)[ii];
sl@0
   908
			if (name.MatchF(aFileName)==0)
sl@0
   909
				{
sl@0
   910
				iMessageQueue->AddItem(aFileName);
sl@0
   911
				if (!iNotificationPullMsg.IsNull())
sl@0
   912
  					{
sl@0
   913
  					iNotificationPullMsg.Complete(KErrNone);
sl@0
   914
  					}
sl@0
   915
				iReleasedFiles->Delete(ii);
sl@0
   916
				}
sl@0
   917
			}
sl@0
   918
		if (iReleasedFiles->Count()==0)
sl@0
   919
			{
sl@0
   920
			delete iReleasedFiles;
sl@0
   921
			iReleasedFiles=NULL;
sl@0
   922
			if (iClosedFiles==NULL && BackupServer()->IsClientBusy(iUniqueClientId))
sl@0
   923
				{
sl@0
   924
				BackupServer()->SetBusy(0);
sl@0
   925
				}
sl@0
   926
			}
sl@0
   927
		}
sl@0
   928
	}
sl@0
   929
sl@0
   930
/**
sl@0
   931
 *
sl@0
   932
 * Allows the session to handle the error.
sl@0
   933
 *
sl@0
   934
 * @param		"TInt aError"
sl@0
   935
 *				The error.
sl@0
   936
 */
sl@0
   937
EXPORT_C void CBaServBackupSession::HandleError(TInt aError)
sl@0
   938
	{
sl@0
   939
	if (aError==KLeaveWithoutAlert)
sl@0
   940
		{
sl@0
   941
		CBaServBackupScheduler::Current()->SetErrorHandler(NULL);
sl@0
   942
		}
sl@0
   943
	}
sl@0
   944
sl@0
   945
void CBaServBackupSession::DoServiceL(TCompletionType& aCompleteType)
sl@0
   946
	{
sl@0
   947
	switch (iClientMessage->Function())
sl@0
   948
		{
sl@0
   949
	case EBakOpCodeEventReady:
sl@0
   950
		{
sl@0
   951
		HandleEventReadyL();
sl@0
   952
		aCompleteType = ECompleteAsync;
sl@0
   953
		}
sl@0
   954
		break;
sl@0
   955
	case EBakOpCodeStopNotifications:
sl@0
   956
		{
sl@0
   957
		StopNotifications();
sl@0
   958
		}
sl@0
   959
		break;
sl@0
   960
	case EBakOpCodeGetEvent:
sl@0
   961
		GetEventL();
sl@0
   962
		break;
sl@0
   963
	case EBakOpCodeCloseAllFiles:
sl@0
   964
		{
sl@0
   965
		aCompleteType = CloseAllFilesL(iClientMessage->Message());
sl@0
   966
		}
sl@0
   967
		break;
sl@0
   968
	case EBakOpCodeRestartAll:
sl@0
   969
		RestartAll();
sl@0
   970
		break;
sl@0
   971
	case EBakOpCodeCloseFile:
sl@0
   972
		CloseFileL();
sl@0
   973
		break;
sl@0
   974
	case EBakOpCodeRestartFile:
sl@0
   975
		RestartFileL();
sl@0
   976
		break;
sl@0
   977
	case EBakOpCodeNotifyLockChange:
sl@0
   978
		NotifyLockChangeL();
sl@0
   979
		break;
sl@0
   980
	case EBakOpCodeNotifyLockChangeCancel:
sl@0
   981
		NotifyLockChangeCancelL();
sl@0
   982
		break;
sl@0
   983
	case EBakOpCodeNotifyBackupOperation:
sl@0
   984
		NotifyBackupOperationL();
sl@0
   985
		break;
sl@0
   986
	case EBakOpCodeCancelOutstandingBackupOperationEvent:
sl@0
   987
		{
sl@0
   988
		iBackupOperationObserverPresent = EFalse;
sl@0
   989
		if (!iBackupOperationMessagePtr.IsNull())
sl@0
   990
			{
sl@0
   991
			GetBackupOperationEventL(iBackupOperationMessagePtr);
sl@0
   992
			iBackupOperationMessagePtr.Complete(KErrCancel);
sl@0
   993
			}
sl@0
   994
		}
sl@0
   995
		break;
sl@0
   996
	case EBakOpCodeGetBackupOperationState:
sl@0
   997
		GetBackupOperationStateL();
sl@0
   998
		break;
sl@0
   999
	case EBakOpCodeBackupOperationEventReady:
sl@0
  1000
		BackupOperationEventReadyL();
sl@0
  1001
		aCompleteType = ECompleteAsync;
sl@0
  1002
		break;
sl@0
  1003
	case EBakOpCodeGetBackupOperationEvent:
sl@0
  1004
		GetBackupOperationEventL(iClientMessage->Message());
sl@0
  1005
		break;
sl@0
  1006
	case EBakOpCodeSetBackupOperationObserverIsPresent:
sl@0
  1007
		{
sl@0
  1008
		iBackupOperationObserverPresent = iClientMessage->GetIntL(0);
sl@0
  1009
		}
sl@0
  1010
		break;
sl@0
  1011
	default:
sl@0
  1012
		User::Leave(KErrNotSupported);
sl@0
  1013
		break;
sl@0
  1014
		}
sl@0
  1015
	}
sl@0
  1016
sl@0
  1017
sl@0
  1018
/**
sl@0
  1019
 *
sl@0
  1020
 * Handles the servicing of client requests passed to the backup server.
sl@0
  1021
 *
sl@0
  1022
 * @param		"const RMessage& aMessage"
sl@0
  1023
 *				The message containing the client request.
sl@0
  1024
 */
sl@0
  1025
EXPORT_C void CBaServBackupSession::ServiceL(const RMessage2& aMessage)
sl@0
  1026
	{
sl@0
  1027
	
sl@0
  1028
	TCompletionType completionType = ECompleteSync;
sl@0
  1029
	
sl@0
  1030
	BSUL::CClientMessage* clientMessage = 0;
sl@0
  1031
	clientMessage = BSUL::CClientMessage::NewL(aMessage);
sl@0
  1032
	
sl@0
  1033
	//Push iClientMessage onto the cleanupstack. Although an instance variable, 
sl@0
  1034
	//the lifetime of the object is contained to this function so it needs to
sl@0
  1035
	//be pushed and popped here as it is not deleted in the destructor
sl@0
  1036
	CleanupStack::PushL(clientMessage);
sl@0
  1037
	
sl@0
  1038
	//Validate the message
sl@0
  1039
	TRAPD(error, clientMessage->ValidateL());
sl@0
  1040
	
sl@0
  1041
	iClientMessage = clientMessage;
sl@0
  1042
	
sl@0
  1043
	if(error == KErrNone)	
sl@0
  1044
		{
sl@0
  1045
		TRAP(error, DoServiceL(completionType));
sl@0
  1046
		}
sl@0
  1047
	
sl@0
  1048
	if(completionType == ECompleteSync)
sl@0
  1049
		{
sl@0
  1050
		if (error==KLeaveWithoutAlert)
sl@0
  1051
			{
sl@0
  1052
			CBaServBackupScheduler::Current()->SetErrorHandler(NULL);
sl@0
  1053
			}
sl@0
  1054
		else
sl@0
  1055
			{
sl@0
  1056
			iClientMessage->CompleteRequestL(error);
sl@0
  1057
			}
sl@0
  1058
		}
sl@0
  1059
	
sl@0
  1060
	//Pop and destroy message
sl@0
  1061
	CleanupStack::PopAndDestroy(clientMessage);
sl@0
  1062
	clientMessage = NULL;
sl@0
  1063
	iClientMessage = NULL;
sl@0
  1064
	}
sl@0
  1065
sl@0
  1066
void CBaServBackupSession::HandleEventReadyL()
sl@0
  1067
	{
sl@0
  1068
	if (iReRegistrationTimer->IsActive())
sl@0
  1069
		{ // If timer is still active (ie not timed out) we need to increment the counter and cancel the timer
sl@0
  1070
		BackupServer()->IncrementFilesReRegistrationCount();	
sl@0
  1071
		iReRegistrationTimer->Cancel();
sl@0
  1072
		}
sl@0
  1073
		// else timer is already inactive because it's expired
sl@0
  1074
	
sl@0
  1075
	if (iMessageQueue->IsEmpty())
sl@0
  1076
		{
sl@0
  1077
		iNotificationPullMsg = iClientMessage->Message();
sl@0
  1078
		}	
sl@0
  1079
	else
sl@0
  1080
		{
sl@0
  1081
		iClientMessage->CompleteRequestL(KErrNone);
sl@0
  1082
		}
sl@0
  1083
	}
sl@0
  1084
sl@0
  1085
const TInt KEventFileNameOffset=1;
sl@0
  1086
sl@0
  1087
void CBaServBackupSession::GetEventL()
sl@0
  1088
	{
sl@0
  1089
	TFileName fileName;
sl@0
  1090
	MBackupObserver::TFileLockFlags fileFlag;
sl@0
  1091
	if(!iMessageQueue->IsEmpty())
sl@0
  1092
		{
sl@0
  1093
		iMessageQueue->GetHead(fileName,fileFlag);
sl@0
  1094
		TBuf<KEventFileNameOffset> num;
sl@0
  1095
		num.Num((TInt)fileFlag);
sl@0
  1096
		
sl@0
  1097
		iClientMessage->WriteL(0,num,0);
sl@0
  1098
		
sl@0
  1099
		iClientMessage->WriteL(0,fileName,KEventFileNameOffset);
sl@0
  1100
	
sl@0
  1101
		iMessageQueue->RemoveHead();	
sl@0
  1102
		}
sl@0
  1103
	else
sl@0
  1104
		{
sl@0
  1105
		iClientMessage->PanicClient(KPanic,ENoEventToFetch);
sl@0
  1106
		User::Leave(KLeaveWithoutAlert);
sl@0
  1107
		}
sl@0
  1108
	}
sl@0
  1109
sl@0
  1110
void CBaServBackupSession::CleanupCloseAllFiles(TAny* aPtr)
sl@0
  1111
	{ // static
sl@0
  1112
	CBaServBackupSession* self=REINTERPRET_CAST(CBaServBackupSession*,aPtr);
sl@0
  1113
	delete self->iClosedFiles;
sl@0
  1114
	self->iClosedFiles=NULL;
sl@0
  1115
	self->BackupServer()->RestartAll();
sl@0
  1116
	}
sl@0
  1117
sl@0
  1118
/**
sl@0
  1119
 Asks the server to close all files. This function may leave in case the server is busy.
sl@0
  1120
 If the requesting client is the current busy client and it has already requested CloseAll,
sl@0
  1121
 this request will be ignored.
sl@0
  1122
 
sl@0
  1123
 @param	aMessage The reference to the message containing the client request: file lock.
sl@0
  1124
 @leave KErrServerBusy if the requesting client is not the busy client. Plus other system-wide 
sl@0
  1125
 errors.
sl@0
  1126
 */
sl@0
  1127
EXPORT_C TCompletionType CBaServBackupSession::CloseAllFilesL(const RMessage2& aMessage)
sl@0
  1128
	{
sl@0
  1129
	// Raise file lock notifications
sl@0
  1130
	TRAPD(err,DoCloseAllFilesL(aMessage));
sl@0
  1131
	
sl@0
  1132
	if (err == KErrNone)
sl@0
  1133
		{
sl@0
  1134
		// Start timer to check all file locks re-registered before completing message
sl@0
  1135
		BackupServer()->StartCloseAllFilesOperationTimer(aMessage);
sl@0
  1136
		}
sl@0
  1137
	else
sl@0
  1138
		{
sl@0
  1139
		// If the error is that the same client has already requested CloseAll, ignore this request
sl@0
  1140
		// If not this error, recover the CloseAllOperationRunningState flag and leave with the error.
sl@0
  1141
		if (err != KErrAlreadyExists) 
sl@0
  1142
			{
sl@0
  1143
			BackupServer()->SetCloseAllOperationRunningState(EFalse);
sl@0
  1144
			User::Leave(err);
sl@0
  1145
			}
sl@0
  1146
		}
sl@0
  1147
sl@0
  1148
	return ECompleteAsync;
sl@0
  1149
	}
sl@0
  1150
sl@0
  1151
void CBaBackupServer::IncrementRegisteredFilesCount()
sl@0
  1152
	{
sl@0
  1153
	iRegisteredFilesCount++;
sl@0
  1154
	}
sl@0
  1155
sl@0
  1156
void CBaBackupServer::DecrementRegisteredFilesCount(TInt aNumberFiles)
sl@0
  1157
	{
sl@0
  1158
	iRegisteredFilesCount = iRegisteredFilesCount - aNumberFiles;
sl@0
  1159
	}
sl@0
  1160
sl@0
  1161
void CBaBackupServer::IncrementFilesReRegistrationCount()
sl@0
  1162
	{
sl@0
  1163
	iSessionLockReRegistrationCount++;
sl@0
  1164
	}
sl@0
  1165
sl@0
  1166
/**
sl@0
  1167
 Function called by both base and derived backup sessions in order to start asynchronous 
sl@0
  1168
 file lock notifications.
sl@0
  1169
 The requesting client is set to the current busy client.
sl@0
  1170
 
sl@0
  1171
 @leave KErrServerBusy if the requesting client is not the current busy client or the server
sl@0
  1172
 is under CloseAll operation. KErrAlreadyExists if the same client has sent CloseAll request.
sl@0
  1173
 Plus other system-wide errors.
sl@0
  1174
 */
sl@0
  1175
 
sl@0
  1176
EXPORT_C TCompletionType CBaServBackupSession::DoCloseAllFilesL(const RMessage2& /*aMessage*/)
sl@0
  1177
	{
sl@0
  1178
	CBaBackupServer* server=BackupServer();
sl@0
  1179
	if (server->IsOtherClientBusy(iUniqueClientId))
sl@0
  1180
		{
sl@0
  1181
		User::Leave(KErrServerBusy);
sl@0
  1182
		}
sl@0
  1183
		
sl@0
  1184
	if (BackupServer()->IsCloseAllOperationRunning())
sl@0
  1185
		{
sl@0
  1186
		User::Leave(KErrAlreadyExists);
sl@0
  1187
		}		
sl@0
  1188
		
sl@0
  1189
	CleanupStack::PushL(TCleanupItem(CleanupCloseAllFiles,this));
sl@0
  1190
	if (iClosedFiles)
sl@0
  1191
		{
sl@0
  1192
		delete iClosedFiles;
sl@0
  1193
		iClosedFiles=NULL;
sl@0
  1194
		}
sl@0
  1195
	server->SetBusy(iUniqueClientId);
sl@0
  1196
	
sl@0
  1197
	MBackupObserver::TFileLockFlags fileFlag=
sl@0
  1198
		(MBackupObserver::TFileLockFlags)iClientMessage->GetIntL(0);
sl@0
  1199
	server->CloseAllFilesL(fileFlag);
sl@0
  1200
	
sl@0
  1201
	iClosedFiles=new(ELeave) CArrayFixSeg<CBaServBackupSession::TClosedFile>(1);
sl@0
  1202
	CBaServBackupScheduler::Current()->SetErrorHandler(this);
sl@0
  1203
	CleanupStack::Pop(); // CleanupCloseAllFiles
sl@0
  1204
	return ECompleteAsync;
sl@0
  1205
	}
sl@0
  1206
sl@0
  1207
/**
sl@0
  1208
 *
sl@0
  1209
 * Asks the server to signal all clients of getting the lock of their respective files.
sl@0
  1210
 *
sl@0
  1211
 */
sl@0
  1212
EXPORT_C void CBaServBackupSession::RestartAll()
sl@0
  1213
	{
sl@0
  1214
	CBaBackupServer* server=BackupServer();	
sl@0
  1215
	if (server->IsClientBusy(iUniqueClientId))
sl@0
  1216
		{
sl@0
  1217
		DoRestartAll();
sl@0
  1218
		}
sl@0
  1219
	}
sl@0
  1220
sl@0
  1221
void CBaServBackupSession::DoRestartAll()
sl@0
  1222
	{
sl@0
  1223
	CBaBackupServer* server=BackupServer();	
sl@0
  1224
	server->RestartAll();
sl@0
  1225
	delete iReleasedFiles;
sl@0
  1226
	iReleasedFiles=NULL;
sl@0
  1227
	if (iClosedFiles)
sl@0
  1228
		{
sl@0
  1229
		CArrayFix<CBaServBackupSession::TClosedFile>* closedFiles=iClosedFiles;
sl@0
  1230
		iClosedFiles=NULL;
sl@0
  1231
		server->CompleteClosingFiles(closedFiles); // takes ownership of closedFiles immediately
sl@0
  1232
		}
sl@0
  1233
	}
sl@0
  1234
sl@0
  1235
/**
sl@0
  1236
Handle the client's request to close a file.
sl@0
  1237
The request will be ignored if the requesting client the current busy client and the server is
sl@0
  1238
under CloseAll operation.
sl@0
  1239
sl@0
  1240
@leave KErrServerBusy if the server is busy with the other client, plus other system-wide errors.
sl@0
  1241
*/
sl@0
  1242
void CBaServBackupSession::CloseFileL()
sl@0
  1243
	{
sl@0
  1244
	CBaBackupServer* server=BackupServer();
sl@0
  1245
	if (server->IsOtherClientBusy(iUniqueClientId))
sl@0
  1246
		{
sl@0
  1247
		User::Leave(KErrServerBusy);
sl@0
  1248
		}
sl@0
  1249
sl@0
  1250
	if (! server->IsCloseAllOperationRunning())
sl@0
  1251
		{
sl@0
  1252
		MBackupObserver::TFileLockFlags flag=
sl@0
  1253
			static_cast<MBackupObserver::TFileLockFlags>(iClientMessage->GetIntL(2));
sl@0
  1254
		TFileName fileName;
sl@0
  1255
		GetFileNameL(fileName);
sl@0
  1256
		server->SetBusy(iUniqueClientId);
sl@0
  1257
		server->CloseFileL(flag,fileName);
sl@0
  1258
		}
sl@0
  1259
	}
sl@0
  1260
sl@0
  1261
void CBaServBackupSession::RestartFileL()
sl@0
  1262
	{
sl@0
  1263
	TFileName fileName;
sl@0
  1264
	GetFileNameL(fileName);
sl@0
  1265
	BackupServer()->RestartFile(fileName);
sl@0
  1266
	}
sl@0
  1267
sl@0
  1268
/**
sl@0
  1269
Handles the client's request of notification of a file lock change.
sl@0
  1270
  
sl@0
  1271
@leave KErrServerBusy if the server is under CloseAll operation, KLeaveWithoutAlert if the requested 
sl@0
  1272
 file has been registered. Plus other system-wide errors.
sl@0
  1273
*/
sl@0
  1274
void CBaServBackupSession::NotifyLockChangeL()
sl@0
  1275
	{
sl@0
  1276
	if(BackupServer()->IsCloseAllOperationRunning())
sl@0
  1277
		{
sl@0
  1278
		User::Leave(KErrServerBusy);
sl@0
  1279
		}
sl@0
  1280
		
sl@0
  1281
	TFileName fileName;
sl@0
  1282
	GetFileNameL(fileName);
sl@0
  1283
	if (iFileLockObservers==NULL)
sl@0
  1284
		{
sl@0
  1285
		iFileLockObservers=new(ELeave) CDesCArraySeg(1);
sl@0
  1286
		}
sl@0
  1287
	else
sl@0
  1288
		{
sl@0
  1289
		TInt pos;
sl@0
  1290
		if(iFileLockObservers->Find(fileName,pos)== KErrNone)
sl@0
  1291
			{
sl@0
  1292
			iClientMessage->PanicClient(KPanic,EReqAlreadyOutstanding);
sl@0
  1293
			User::Leave(KLeaveWithoutAlert);
sl@0
  1294
			}		
sl@0
  1295
		}
sl@0
  1296
	iFileLockObservers->AppendL(fileName);
sl@0
  1297
	BackupServer()->IncrementRegisteredFilesCount();
sl@0
  1298
	}
sl@0
  1299
sl@0
  1300
LOCAL_C void RemoveFileName(CDesCArray& aArray,const TDesC& aFileName)
sl@0
  1301
	{
sl@0
  1302
	TInt pos;
sl@0
  1303
	if (aArray.Find(aFileName,pos)==KErrNone)
sl@0
  1304
		{
sl@0
  1305
		aArray.Delete(pos);
sl@0
  1306
		}
sl@0
  1307
	}
sl@0
  1308
sl@0
  1309
void CBaServBackupSession::NotifyLockChangeCancelL()
sl@0
  1310
	{
sl@0
  1311
	TFileName fileName;
sl@0
  1312
	GetFileNameL(fileName);
sl@0
  1313
	if (iFileLockObservers)
sl@0
  1314
		{
sl@0
  1315
		RemoveFileName(*iFileLockObservers,fileName);
sl@0
  1316
		BackupServer()->DecrementRegisteredFilesCount();
sl@0
  1317
		}
sl@0
  1318
	if (iReleasedFiles)
sl@0
  1319
		{
sl@0
  1320
		RemoveFileName(*iReleasedFiles,fileName);
sl@0
  1321
		}
sl@0
  1322
	iMessageQueue->RemoveItem(fileName);
sl@0
  1323
  	}
sl@0
  1324
sl@0
  1325
void CBaServBackupSession::GetFileNameL(TDes& aFileName)
sl@0
  1326
	{
sl@0
  1327
	//The verification of this parameter has already been handled
sl@0
  1328
	//by the CClientMessage class so we can safely read the value
sl@0
  1329
	iClientMessage->ReadL(1,aFileName);
sl@0
  1330
	}
sl@0
  1331
sl@0
  1332
sl@0
  1333
void CBaServBackupSession::GetBackupOperationEventL(const RMessagePtr2& aPtr)
sl@0
  1334
	{
sl@0
  1335
	TPckg<TBackupOperationAttributes> backupOpAttPkg(iBackupOperationAttributes);
sl@0
  1336
	
sl@0
  1337
	aPtr.WriteL(0, backupOpAttPkg);
sl@0
  1338
	}
sl@0
  1339
sl@0
  1340
void CBaServBackupSession::BackupOperationEventReadyL()
sl@0
  1341
	{
sl@0
  1342
	if (iBackupOperationObserverPresent)
sl@0
  1343
		{
sl@0
  1344
		iBackupOperationMessagePtr = iClientMessage->Message();
sl@0
  1345
		}
sl@0
  1346
	else
sl@0
  1347
		{
sl@0
  1348
		iClientMessage->CompleteRequestL(KErrNone);
sl@0
  1349
		}
sl@0
  1350
	}
sl@0
  1351
sl@0
  1352
void CBaServBackupSession::NotifyBackupOperationL()
sl@0
  1353
	{
sl@0
  1354
	CBaBackupServer* server=BackupServer();
sl@0
  1355
	if (server->CBaBackupServer::IsOtherClientBusy(iUniqueClientId))
sl@0
  1356
		{
sl@0
  1357
		User::Leave(KErrServerBusy);
sl@0
  1358
		}
sl@0
  1359
	TPckg<TBackupOperationAttributes> backupOpAttPkg(iBackupOperationAttributes);
sl@0
  1360
	
sl@0
  1361
	iClientMessage->ReadL(0,backupOpAttPkg);
sl@0
  1362
sl@0
  1363
	const TBool backupOperationRunning = ((iBackupOperationAttributes.iOperation==MBackupOperationObserver::EStart) ? ETrue : EFalse);
sl@0
  1364
	server->SetBackupOperationRunning(backupOperationRunning);
sl@0
  1365
	server->SetBusy(backupOperationRunning ? iUniqueClientId : 0);
sl@0
  1366
	server->SignalBackupOperation(iBackupOperationAttributes);
sl@0
  1367
	if (!iBackupOperationMessagePtr.IsNull())
sl@0
  1368
		{
sl@0
  1369
		GetBackupOperationEventL(iBackupOperationMessagePtr);
sl@0
  1370
		iBackupOperationMessagePtr.Complete(KErrCancel);
sl@0
  1371
		}
sl@0
  1372
	}
sl@0
  1373
sl@0
  1374
void CBaServBackupSession::GetBackupOperationStateL()
sl@0
  1375
	{
sl@0
  1376
	const TBool isRunning = BackupServer()->IsBackupOperationRunning();
sl@0
  1377
	TPckgC<TBool> pkgObs(isRunning);
sl@0
  1378
sl@0
  1379
	iClientMessage->WriteL(0, pkgObs);
sl@0
  1380
	}
sl@0
  1381
sl@0
  1382
void CBaServBackupSession::SignalBackupOperation(const TBackupOperationAttributes& aBackupOperationAttributes)
sl@0
  1383
	{
sl@0
  1384
	iBackupOperationAttributes = aBackupOperationAttributes;
sl@0
  1385
	if (!iBackupOperationMessagePtr.IsNull())
sl@0
  1386
		{
sl@0
  1387
		TRAPD(err,GetBackupOperationEventL(iBackupOperationMessagePtr));
sl@0
  1388
		iBackupOperationMessagePtr.Complete(err);
sl@0
  1389
		}
sl@0
  1390
	}
sl@0
  1391
sl@0
  1392
void CBaServBackupSession::StopNotifications()
sl@0
  1393
	{
sl@0
  1394
		if(!iNotificationPullMsg.IsNull())
sl@0
  1395
		{// complete the registration message
sl@0
  1396
		iNotificationPullMsg.Complete(KErrNone);
sl@0
  1397
		}
sl@0
  1398
	}
sl@0
  1399
sl@0
  1400
/**
sl@0
  1401
@internalComponent
sl@0
  1402
*/
sl@0
  1403
CBaServBackupSession::CReRegistrationTimer* CBaServBackupSession::CReRegistrationTimer::NewL(TInt aPriority)
sl@0
  1404
	{ // static
sl@0
  1405
	CBaServBackupSession::CReRegistrationTimer* self=new(ELeave) CBaServBackupSession::CReRegistrationTimer(aPriority);
sl@0
  1406
	CleanupStack::PushL(self);
sl@0
  1407
	self->ConstructL();
sl@0
  1408
	CleanupStack::Pop(); // self
sl@0
  1409
	CActiveScheduler::Add(self);
sl@0
  1410
	return self;
sl@0
  1411
	}
sl@0
  1412
sl@0
  1413
/**
sl@0
  1414
@internalComponent
sl@0
  1415
*/
sl@0
  1416
TInt CBaServBackupSession::CReRegistrationTimer::RunError(TInt aError)
sl@0
  1417
	{
sl@0
  1418
	if (aError==KLeaveWithoutAlert)
sl@0
  1419
		{
sl@0
  1420
		return KErrNone;
sl@0
  1421
		}
sl@0
  1422
	return aError;
sl@0
  1423
	}
sl@0
  1424
	
sl@0
  1425
/**
sl@0
  1426
@internalComponent
sl@0
  1427
*/
sl@0
  1428
CBaServBackupSession::CReRegistrationTimer::CReRegistrationTimer(TInt aPriority)
sl@0
  1429
	: CPeriodic(aPriority)
sl@0
  1430
	{ }
sl@0
  1431
	
sl@0
  1432
/**
sl@0
  1433
@internalComponent
sl@0
  1434
*/
sl@0
  1435
TInt CBaServBackupSession::CReRegistrationTimer::ReRegistrationTimerCallBack(TAny* aPtr)
sl@0
  1436
	{ // static
sl@0
  1437
	TRAP_IGNORE(REINTERPRET_CAST(CBaServBackupSession::CReRegistrationTimer*,aPtr)->HandleReRegistrationTimerCallBack());
sl@0
  1438
	return 0;
sl@0
  1439
	}
sl@0
  1440
sl@0
  1441
/**
sl@0
  1442
@internalComponent
sl@0
  1443
*/
sl@0
  1444
void CBaServBackupSession::CReRegistrationTimer::HandleReRegistrationTimerCallBack()
sl@0
  1445
	{
sl@0
  1446
	iBackupServer->IncrementFilesReRegistrationCount();
sl@0
  1447
	
sl@0
  1448
	if (IsActive())
sl@0
  1449
		{
sl@0
  1450
		Cancel();
sl@0
  1451
		}
sl@0
  1452
	}
sl@0
  1453