os/ossrv/genericservices/taskscheduler/SCHSVR/SSCH_SES.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 // User includes
    17 #include "SSCH_STD.H"
    18 #include "CSCHCODE.H"
    19 #include "SCHCLI.H"
    20 #include "SchLogger.h"
    21 #include "SCHMAN.H"
    22 #include "SCHEDULE.H"
    23 #include <schtask.h>
    24 
    25 // Constants
    26 const TInt KSchedulerArrayGranularity = 1; 
    27 _LIT(KSchedulerPanic, "Task Scheduler");
    28 
    29 void PanicClient(TInt aPanic, const RMessage2& aMessage)
    30 //
    31 // Toast the client
    32 //
    33 	{
    34 	//Note that panic also completes the message so don't complete anywhere else
    35 	aMessage.Panic(KSchedulerPanic,aPanic);
    36 	}
    37 	
    38 CSchSession::CSchSession(CTaskScheduler& aScheduler)
    39 //
    40 // C'Tor - must pass client to CSession
    41 //
    42 	:	CSession2(), 
    43 		iTaskScheduler(&aScheduler), 
    44 		iClient(NULL)
    45 	{
    46 	}
    47 
    48 CSchSession::~CSchSession()
    49 	{
    50 	if (iClient)
    51 		{
    52 		iClient->DecUsers();
    53 		if (!iClient->Users())
    54 			{
    55 			iClient->Remove();
    56 			delete iClient;
    57 			iClient = NULL;
    58 			}
    59 		}
    60 	if(!iPendingNotification.IsNull())
    61 		iPendingNotification.Complete(KErrCancel);	
    62 	}
    63 	
    64 void CSchSession::ServiceError(const RMessage2& aMessage,TInt aError)
    65 //
    66 // Handle an error or leave from CMySession::ServiceL()
    67 // A bad descriptor error implies a badly programmed client, so panic it;
    68 // otherwise use the default handling (report the error to the client)
    69 //
    70 	{
    71 	if (aError==KErrBadDescriptor)
    72 		PanicClient(EPanicBadDescriptor,aMessage);
    73 	CSession2::ServiceError(aMessage,aError);
    74 	}
    75 
    76 void CSchSession::ServiceL(const RMessage2& aMessage)
    77 //
    78 //	Handle messages for this session.
    79 //	all API functions are synchronous so complete here too
    80 //
    81 	{
    82 	
    83 	iClientMessage = BSUL::CClientMessage::NewL(aMessage);
    84 	
    85 	//Validate the message
    86 	TRAPD(error, iClientMessage->ValidateL());
    87 	
    88 	if(error == KErrNone)
    89 		{
    90 		TRAP(error, DoServiceL());
    91 		}
    92 	
    93    	// don't complete message if we have paniced client (ie message is NULL)
    94    	iClientMessage->CompleteRequestL(error);
    95 
    96    	delete iClientMessage;
    97    	iClientMessage = NULL;   	
    98 	}
    99 
   100 void CSchSession::DoServiceL()
   101 //
   102 //	Handle messages for this session.
   103 //	all API functions are synchronous so complete here too
   104 //
   105 	{
   106 	switch (iClientMessage->Function())
   107 		{
   108 #if defined (_DEBUG)
   109 	case ESchDbgMarkHeap:
   110 		__UHEAP_MARK;
   111 		break;
   112 	case ESchDbgCheckHeap:
   113 		__UHEAP_CHECK(iClientMessage->GetIntL(0));
   114 		break;
   115 	case ESchDbgMarkEnd:
   116 		{
   117 		TInt count = iClientMessage->GetIntL(0);
   118 		
   119 		//Three allocations are made for this message so add 3 to count
   120 		//CClientMessage::NewL
   121 		//CIntParameter::NewL
   122 		//RPointerArray::AppendL	
   123 		__UHEAP_MARKENDC(count + 3);
   124 		}
   125 		break;
   126 	case ESchDbgFailNext:
   127 		__UHEAP_FAILNEXT(iClientMessage->GetIntL(0));
   128 		break;
   129 	case ESchDbgResetHeap:
   130 		__UHEAP_RESET;
   131 		break;
   132 	case ESchFaultServer:
   133 		{
   134 		// make sure we complete the message first before Killing this server
   135 		iClientMessage->CompleteRequestL(KErrNone);
   136 		RProcess().Kill(0);
   137 		return;
   138 		}
   139 #endif
   140     case ERegisterClient:
   141 		RegisterClientL();
   142     	break;
   143 	case ECreateTimeSchedule:
   144 		CreateTimeScheduleL();
   145     	break;
   146 	case ECreateConditionSchedule:
   147 		CreateConditionScheduleL();
   148     	break;
   149 	case EScheduleTask:
   150 		ScheduleTaskL();
   151     	break;
   152 	case EDeleteTask:
   153 		DeleteTaskL();
   154 		break;
   155 	case EDeleteSchedule:
   156 		{
   157 		CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(0));
   158 		CheckPersistsInBackupL(*schedule);
   159 		//check that user has permission to delete this schedule.
   160 		schedule->CheckAccessAllowedL(iClientMessage->Message());
   161 		iTaskScheduler->RemoveScheduleL(iClientMessage->GetIntL(0));
   162     	break;
   163 		}
   164 	case EDisableSchedule:
   165 		{
   166 		CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(0));
   167 		CheckPersistsInBackupL(*schedule);
   168 		//check that user has permission to disable this schedule.
   169 		schedule->CheckAccessAllowedL(iClientMessage->Message());
   170 		iTaskScheduler->DisableScheduleL(iClientMessage->GetIntL(0));
   171     	break;
   172 		}
   173 	case EEnableSchedule:
   174 		{
   175 		CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(0));
   176 		CheckPersistsInBackupL(*schedule);
   177 		//check that user has permission to enable this schedule.
   178 		schedule->CheckAccessAllowedL(iClientMessage->Message());
   179 		iTaskScheduler->EnableScheduleL(iClientMessage->GetIntL(0));
   180     	break;
   181 		}
   182 	case EEditTimeSchedule:
   183 		EditTimeScheduleL();
   184     	break;
   185 	case EEditConditionSchedule:
   186 		EditConditionScheduleL();
   187     	break;
   188 	case EGetScheduleRefs:
   189 		GetScheduleRefsL();
   190 		break;
   191 	case ECountSchedules:
   192 		CountSchedulesL();
   193 		break;
   194 	case EGetScheduleInfo:
   195 		GetScheduleInfoL();
   196 		break;
   197 	case EGetTimeScheduleData:
   198 		GetTimeScheduleDataL();
   199 		break;
   200 	case EGetConditionScheduleData:
   201 		GetConditionScheduleDataL();
   202 		break;
   203 	case EGetTaskData:
   204 		GetTaskDataL();
   205 		break;
   206 	case EGetTaskRefs:
   207 		GetTaskRefsL();
   208     	break;	
   209 	case ECountTasks:
   210 		CountTasksL();
   211 		break;
   212 	case EGetTask:
   213 		GetTaskInfoL();
   214 		break;
   215 	case EGetSchedulerItemRefAndNextDueTime:
   216 		GetScheduleItemRefAndDueTimeL();
   217 		break;
   218 	case EGetTaskDataSize:
   219 		GetTaskDataSizeL();
   220 		break;
   221 	case EGetScheduleType:
   222 		GetScheduleTypeL();
   223 		break;
   224 	default:
   225 		User::Leave(EPanicIllegalFunction);
   226 		break;
   227 		
   228         }//switch 
   229 
   230 	}
   231 
   232 //private functions
   233 void CSchSession::RegisterClientL()
   234 	{
   235 	TFileName writeBuf;
   236 
   237 	iClientMessage->ReadL(0,writeBuf);
   238 
   239 	// should return existing client if there is one
   240 	CClientProxy* client = iTaskScheduler->AddClientL(writeBuf, iClientMessage->GetIntL(1));
   241 	client->IncUsers();
   242 	if	(iClient)
   243 		{
   244 		iClient->DecUsers();
   245 		if	(!iClient->Users())
   246 			{
   247 			LOGSTRING2("CSchSession::RegisterClientL - removing existing client %S", &iClient->ExecutorFileName());
   248 			iClient->Remove();
   249 			delete iClient;
   250 			}
   251 		}
   252 	iClient = client;
   253 	}
   254 
   255 void CSchSession::CreateTimeScheduleL()
   256 	{
   257 	// get settings
   258 	TScheduleSettings2 settings;
   259 	TPScheduleSettings pS(settings);
   260 	iClientMessage->ReadL(0, pS);
   261 	
   262 	//WriteDeviceData needed to create persistent schedules
   263 	if(settings.iPersists)
   264 		{
   265 		// backup or restore in progress, so don't allow functions that might write to store
   266 		if (iTaskScheduler->BUROperationInProgress() != EBUROperationNoActivity)
   267 			{
   268 			User::Leave(KErrServerBusy);
   269 			}
   270 
   271 		CheckCapabilityL();
   272 		}	
   273 
   274 	//Verify that the length of the condition list passed in is as expected
   275 	if(iClientMessage->GetDesLengthL(1) != 
   276 				(settings.iEntryCount * sizeof(TScheduleEntryInfo2)))
   277 		{
   278 		User::Leave(KErrBadDescriptor);
   279 		}
   280 
   281 	// get entries
   282 	CArrayFixFlat<TScheduleEntryInfo2>* entries 
   283 		= new(ELeave) CArrayFixFlat<TScheduleEntryInfo2>(settings.iEntryCount);
   284 	CleanupStack::PushL(entries);
   285 	entries->ResizeL(settings.iEntryCount);
   286 	TPtr8 entriesPtr(REINTERPRET_CAST(TUint8*,&(entries->At(0))), settings.iEntryCount * sizeof(TScheduleEntryInfo2));
   287 	iClientMessage->ReadL(1, entriesPtr);
   288 
   289 	// create schedule
   290 	const TInt handle = iTaskScheduler->GenerateId();
   291 	if	(handle == KErrOverflow)
   292 		User::Leave(KErrOverflow);
   293 
   294 	// write back ID
   295 	TPInt id(handle);
   296 	iClientMessage->WriteL(2,id);
   297 
   298 	// get security info
   299 	TSecurityInfo securityInfo(iClientMessage->Message());	
   300 
   301 	// Create schedule and add to scheduler
   302 	CSchedule* newschedule = CSchedule::NewLC(handle, 
   303 										settings.iName, 
   304 										settings.iPersists, 
   305 										*entries,
   306 										securityInfo);
   307 	iTaskScheduler->AddScheduleL(*newschedule);
   308 	CleanupStack::Pop(newschedule);
   309 	CleanupStack::PopAndDestroy(entries);
   310 	}
   311 
   312 void CSchSession::CreateConditionScheduleL()
   313 	{
   314 	// get settings
   315 	TScheduleSettings2 settings;
   316 	TPScheduleSettings pS(settings);
   317 	iClientMessage->ReadL(0, pS);
   318 
   319 	//WriteDeviceData needed to create persistent schedules
   320 	if(settings.iPersists)
   321 		{
   322 		// backup or restore in progress, so don't allow functions that might write to store
   323 		if (iTaskScheduler->BUROperationInProgress() != EBUROperationNoActivity)
   324 			{
   325 			User::Leave(KErrServerBusy);
   326 			}
   327 
   328 		CheckCapabilityL();
   329 		}
   330 
   331 	//Verify that the length of the condition list passed in is as expected
   332 	if(iClientMessage->GetDesLengthL(1) != 
   333 				(settings.iEntryCount * sizeof(TTaskSchedulerCondition)))
   334 		{
   335 		User::Leave(KErrBadDescriptor);
   336 		}
   337 
   338 	// get entries
   339 	CArrayFixFlat<TTaskSchedulerCondition>* entries 
   340 		= new(ELeave) CArrayFixFlat<TTaskSchedulerCondition>(settings.iEntryCount);
   341 	CleanupStack::PushL(entries);
   342 	entries->ResizeL(settings.iEntryCount);
   343 	TPtr8 entriesPtr(REINTERPRET_CAST(TUint8*,&(entries->At(0))), settings.iEntryCount * sizeof(TTaskSchedulerCondition));
   344 	iClientMessage->ReadL(1, entriesPtr);
   345 	
   346 	// get time
   347 	TTsTime defaultRunTime;
   348 	TPckg<TTsTime> pTime(defaultRunTime);
   349 	iClientMessage->ReadL(2, pTime);
   350 
   351 	// create schedule
   352 	const TInt handle = iTaskScheduler->GenerateId();
   353 	if	(handle == KErrOverflow)
   354 		User::Leave(KErrOverflow);
   355 
   356 	// write back ID
   357 	TPInt id(handle);
   358 	iClientMessage->WriteL(3,id);
   359 	
   360 	// get security info
   361 	TSecurityInfo securityInfo(iClientMessage->Message());	
   362 
   363 	// Create schedule and add to scheduler
   364 	CSchedule* newschedule 
   365 		= CSchedule::NewLC(handle, 
   366 							settings.iName, 
   367 							settings.iPersists, 
   368 							*entries,
   369 							defaultRunTime,
   370 							securityInfo);
   371 	iTaskScheduler->AddScheduleL(*newschedule);
   372 	CleanupStack::Pop(newschedule);
   373 	CleanupStack::PopAndDestroy(entries);
   374 	}
   375 
   376 void CSchSession::EditTimeScheduleL()
   377 	{
   378 	CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(1));
   379 	
   380 	CheckPersistsInBackupL(*schedule);
   381 	//check that user has permission to edit this schedule.
   382 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   383 	
   384 	//check that this is a time schedule!
   385 	if(schedule->Type() != ETimeSchedule)
   386 		User::Leave(KErrArgument);
   387 		
   388 	// Get entry count
   389 	const TInt count = iClientMessage->GetIntL(0);
   390 	
   391 	//Verify that the length of the condition list passed in is as expected
   392 	if(iClientMessage->GetDesLengthL(2) != (count * sizeof(TScheduleEntryInfo2)))
   393 		{
   394 		User::Leave(KErrBadDescriptor);
   395 		}
   396 
   397 	// Get new entry list
   398 	CArrayFixFlat<TScheduleEntryInfo2>* entries 
   399 		= new(ELeave) CArrayFixFlat<TScheduleEntryInfo2> (KSchedulerArrayGranularity);	
   400 	CleanupStack::PushL(entries);
   401 	entries->ResizeL(count);
   402 	TPtr8 entriesPtr(REINTERPRET_CAST(TUint8*, &(entries->At(0))), count*sizeof(TScheduleEntryInfo2));
   403 
   404 	iClientMessage->ReadL(2, entriesPtr);
   405 
   406 	// Give it to scheduler along with schedule id
   407 	iTaskScheduler->EditScheduleL(iClientMessage->GetIntL(1), *entries);
   408 	CleanupStack::PopAndDestroy(entries);
   409 	}
   410 
   411 void CSchSession::EditConditionScheduleL()
   412 	{
   413 	CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(1));
   414 	
   415 	CheckPersistsInBackupL(*schedule);
   416 	//check that user has permission to edit this schedule.
   417 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   418 	
   419 	//check that this is a condition schedule!
   420 	if(schedule->Type() != EConditionSchedule)
   421 		User::Leave(KErrArgument);
   422 
   423 	// Get entry count
   424 	const TInt count = iClientMessage->GetIntL(0);
   425 	
   426 	//Verify that the length of the condition list passed in is as expected
   427 	if(iClientMessage->GetDesLengthL(2) != (count * sizeof(TTaskSchedulerCondition)))
   428 		{
   429 		User::Leave(KErrBadDescriptor);
   430 		}
   431 
   432 	// Get new entry list
   433 	CArrayFixFlat<TTaskSchedulerCondition>* entries 
   434 		= new(ELeave) CArrayFixFlat<TTaskSchedulerCondition> (KSchedulerArrayGranularity);	
   435 	CleanupStack::PushL(entries);
   436 	entries->ResizeL(count);
   437 	TPtr8 entriesPtr(REINTERPRET_CAST(TUint8*, &(entries->At(0))), count*sizeof(TTaskSchedulerCondition));
   438 	iClientMessage->ReadL(2, entriesPtr);
   439 
   440 	// get time
   441 	TTsTime defaultRunTime;
   442 	TPckg<TTsTime> pTime(defaultRunTime);
   443 	iClientMessage->ReadL(3, pTime);
   444 
   445 	// Give it to scheduler along with schedule id
   446 	iTaskScheduler->EditScheduleL(iClientMessage->GetIntL(1), *entries, defaultRunTime);
   447 	CleanupStack::PopAndDestroy(entries);
   448 	}
   449 
   450 void CSchSession::ScheduleTaskL()
   451 	{
   452 	// If client is registered, it is allowed to schedule tasks
   453 	if(iClient != NULL)
   454 		{
   455 		TTaskInfo taskInfo;
   456 		TPTaskInfo pI(taskInfo);
   457 		iClientMessage->ReadL(0, pI);
   458 
   459 		CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(1));
   460 	
   461 		CheckPersistsInBackupL(*schedule);
   462 
   463 		//check that user has permission to schedule a task using this schedule.
   464 		schedule->CheckAccessAllowedL(iClientMessage->Message());
   465 	
   466 		taskInfo.iTaskId = schedule->GenerateTaskId();
   467 
   468 		if (taskInfo.iTaskId == KErrOverflow)
   469 			{
   470 			User::Leave(KErrOverflow);
   471 			}
   472 		// panic client if this is a condition schedule and client is asking for 
   473 		// repeats.  This doesnt make sense.	
   474 		if (schedule->Type() == EConditionSchedule && taskInfo.iRepeat != 0)
   475 			User::Leave(KErrArgument); 
   476 
   477 		// Create a new scheduled task with associated task data
   478 		TInt len = iClientMessage->GetDesLengthL(3);
   479 		HBufC* taskdata = HBufC::NewLC(len);
   480 
   481 		TPtr pData(taskdata->Des());
   482 		iClientMessage->ReadL(3, pData);	
   483 	
   484 		CScheduledTask* newTask = new(ELeave) CScheduledTask(taskInfo, 
   485 											taskdata, 
   486 											schedule->Type(), 
   487 											schedule->SecurityInfo());
   488 		CleanupStack::Pop(taskdata); //taskdata now owned by newTask
   489 		CleanupStack::PushL(newTask);
   490 		// Have to store the associated task, so that in the case where the
   491 		// tasks need to be restored from a backup, we can ensure that the
   492 		// task is associated with the correct schedule.
   493 		newTask->SetScheduleId(schedule->Id());
   494 
   495 		//If the schedule that the task is associated with is persistent then set the flag
   496 		if(schedule->Persists())
   497 			{
   498 			newTask->SetPersists();
   499 			}
   500 		LOGSTRING("CSchSession::ScheduleTaskL - writing back task id to client");
   501 		TPInt id(taskInfo.iTaskId);
   502 		iClientMessage->WriteL(2,id);
   503 	
   504 		TScheduledTask* task = new(ELeave) TScheduledTask(*newTask,*iClient);
   505 	
   506 		// Now that task has been created sucessfully, we can add newTask to Client
   507 		iClient->AddTask(*newTask); // task info is owned by client: schedule just keeps a reference
   508 		CleanupStack::Pop(newTask);
   509 
   510 		schedule->AddTask(*task);	//add new task - its now owned by schedule
   511 
   512 		LOGSTRING("CSchSession::ScheduleTaskL - scheduling task with task scheduler");
   513 		// If this leaves we need to still remove task from client and schedule. 
   514 		// No easy way to do this via CleanupStack
   515 		TRAPD(err, iTaskScheduler->ScheduleTaskL(*schedule, *iClient));
   516 		if(err)
   517 			{
   518 			schedule->RemoveTask(task);
   519 			iClient->RemoveTask(newTask);
   520 			User::Leave(err);	
   521 			}
   522 		}
   523 	else
   524 		//Client hasnt been registered so it isn't allowed to schedule task, panic client
   525 		{
   526 		iClientMessage->PanicClient(KSchedulerPanic,EPanicNotRegistered);
   527 		}
   528 	}
   529 
   530 void CSchSession::DeleteTaskL()
   531 	{
   532 	const TInt taskId = iClientMessage->GetIntL(0);
   533 	
   534 	const TInt scheduleId = (taskId/KScheduleIdDifferential)*KScheduleIdDifferential;
   535 
   536 	//check that user has permission to delete a task using this schedule.
   537 	CSchedule* schedule = iTaskScheduler->FindL(scheduleId);
   538 	CheckPersistsInBackupL(*schedule);
   539 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   540 	
   541 	iTaskScheduler->DeleteTaskL(scheduleId, taskId);
   542 	}
   543 
   544 //retrieval functions
   545 void CSchSession::CountSchedulesL()
   546 	{
   547 	TScheduleFilter filter = STATIC_CAST(TScheduleFilter, iClientMessage->GetIntL(1));
   548 	//GetScheduleRefs filters on clients schedule permssion as well.
   549 	TInt count = iTaskScheduler->GetScheduleRefsL(NULL,filter, iClientMessage->Message());
   550 	TPInt pCount(count);
   551 	iClientMessage->WriteL(0,pCount);
   552 	}
   553 
   554 void CSchSession::GetScheduleRefsL()
   555 	{
   556 	//client calls CountSchedules() first to get expected count. still 
   557 	//need to check it's valid though...
   558 	
   559 	const TInt expectedCount = iClientMessage->GetIntL(0);
   560 	TScheduleFilter filter = STATIC_CAST(TScheduleFilter, iClientMessage->GetIntL(1));
   561 
   562 	CArrayFixFlat<TSchedulerItemRef>* refArray 
   563 		= new(ELeave) CArrayFixFlat<TSchedulerItemRef>(KSchedulerArrayGranularity);
   564 	CleanupStack::PushL(refArray);
   565 	
   566 	//GetScheduleRefs filters on clients schedule permssion as well.
   567 	TInt count = iTaskScheduler->GetScheduleRefsL(refArray, filter, iClientMessage->Message());
   568 	if	((expectedCount<count) || (count == 0))
   569 		User::Leave(KErrArgument);
   570 
   571 	TPtrC8 pS(REINTERPRET_CAST(TUint8*, &refArray->At(0)),sizeof(TSchedulerItemRef)*expectedCount);
   572 	iClientMessage->WriteL(2, pS);
   573 	CleanupStack::PopAndDestroy();//info array
   574 	}
   575 
   576 void CSchSession::GetTimeScheduleDataL()
   577 	{
   578 	//client input:handle at info at aMessage.Int0()
   579 	//info at aMessage.Ptr1()
   580 	//info contains: exepcted entry count
   581 	//scheduler output: entries at aM.Ptr2()
   582 	TInt handle = iClientMessage->GetIntL(0);
   583 
   584 	TScheduleInfo info;
   585 	TPScheduleInfo pS(info);
   586 	iClientMessage->ReadL(1, pS);
   587 
   588 	CSchedule* schedule = iTaskScheduler->FindL(handle);
   589 
   590 	//check that user has permission to get this schedules info.
   591 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   592 	
   593 	if (schedule->Type() != ETimeSchedule)
   594 		User::Leave(KErrArgument); //calling wrong API
   595 
   596 	CArrayFixFlat<TScheduleEntryInfo2>* entries 
   597 		= new(ELeave) CArrayFixFlat<TScheduleEntryInfo2> (KSchedulerArrayGranularity);
   598 	CleanupStack::PushL(entries);
   599 	schedule->EntriesL(*entries);
   600 	if ((entries->Count())!=info.iEntryCount)
   601 		User::Leave(KErrArgument);
   602 	//write entries
   603 	TPtrC8 pE(REINTERPRET_CAST(TUint8*, &entries->At(0)),sizeof(TScheduleEntryInfo2)*info.iEntryCount);
   604 	iClientMessage->WriteL(2, pE);	
   605 
   606 	CleanupStack::PopAndDestroy(entries);//entry array
   607 	}
   608 
   609 void CSchSession::GetConditionScheduleDataL()
   610 	{
   611 	//client input:handle at info at aMessage.Int0()
   612 	//info at aMessage.Ptr1()
   613 	//info contains: exepcted entry count
   614 	//scheduler output: entries at aM.Ptr2()
   615 	TInt handle = iClientMessage->GetIntL(0);
   616 
   617 	TScheduleInfo info;
   618 	TPScheduleInfo pS(info);
   619 	iClientMessage->ReadL(1, pS);
   620 
   621 	CSchedule* schedule = iTaskScheduler->FindL(handle);
   622 	
   623 	//check that user has permission to get this schedules info.
   624 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   625 	
   626 	if (schedule->Type() != EConditionSchedule)
   627 		User::Leave(KErrArgument); //calling wrong API
   628 
   629 	CArrayFixFlat<TTaskSchedulerCondition>* conditions 
   630 		= new(ELeave) CArrayFixFlat<TTaskSchedulerCondition> (KSchedulerArrayGranularity);
   631 	CleanupStack::PushL(conditions);
   632 	schedule->ConditionsL(*conditions);
   633 	if ((conditions->Count())!=info.iEntryCount)
   634 		User::Leave(KErrArgument);
   635 	//write entries
   636 	TPtrC8 pE(REINTERPRET_CAST(TUint8*, &conditions->At(0)),sizeof(TTaskSchedulerCondition)*info.iEntryCount);
   637 	iClientMessage->WriteL(2, pE);	
   638 
   639 	//write time
   640 	TTsTime defaultTime(schedule->DefaultRunTimeL());
   641 	TPBTime pDefaultTime(defaultTime);
   642 	iClientMessage->WriteL(3, pDefaultTime);
   643 
   644 	CleanupStack::PopAndDestroy(conditions);//condition array
   645 	}
   646 
   647 void CSchSession::GetScheduleTypeL()
   648 	{
   649 	TScheduleType type;
   650 	TInt handle = iClientMessage->GetIntL(0);
   651 	CSchedule* schedule = iTaskScheduler->FindL(handle);
   652 	
   653 	//check that user has permission to get this schedules info.
   654 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   655 	
   656 	type = schedule->Type();	
   657 	TPInt pType(type);
   658 	iClientMessage->WriteL(1,pType);
   659 	}
   660 	
   661 void CSchSession::GetTaskDataL()
   662 	{//client input:handle at info at aMessage.Int0()
   663 	//info at aMessage.Ptr1()
   664 	//info contains: exepcted entry count, expected task count
   665 	//scheduler output: tasks at aM.Ptr2()
   666 	TInt handle = iClientMessage->GetIntL(0);
   667 
   668 	TScheduleInfo info;
   669 	TPScheduleInfo pS(info);
   670 	iClientMessage->ReadL(1, pS);
   671 
   672 	CSchedule* schedule = iTaskScheduler->FindL(handle);
   673 
   674 	//check that user has permission to get this task info (based on owning
   675 	// schedules info).
   676 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   677 	
   678 	CArrayFixFlat<TTaskInfo>* tasks 
   679 		= new(ELeave) CArrayFixFlat<TTaskInfo> (KSchedulerArrayGranularity);
   680 	CleanupStack::PushL(tasks);
   681 	schedule->TasksL(*tasks);
   682 	if ((tasks->Count())!=info.iTaskCount)
   683 		User::Leave(KErrArgument);
   684 	//write tasks if there are any
   685 	if (info.iTaskCount>0)
   686 		{
   687 		TPtrC8 pT(REINTERPRET_CAST(TUint8*, &tasks->At(0)),sizeof(TTaskInfo)*info.iTaskCount);
   688 		iClientMessage->WriteL(2, pT);	
   689 		}
   690 	CleanupStack::PopAndDestroy(tasks);//task array
   691 	}
   692 
   693 void CSchSession::GetScheduleInfoL()
   694 	{
   695 	CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(0));
   696 	
   697 	//check that user has permission to get this schedules info.
   698 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   699 	
   700 	TScheduleInfo info;
   701 	if (schedule->Type() == ETimeSchedule)
   702 		schedule->GetInfo(info, EFalse);
   703 	else
   704 		schedule->GetInfo(info, ETrue);
   705 		
   706 	TPBScheduleInfo pInfo(info);
   707 	iClientMessage->WriteL(1, pInfo);
   708 	TTsTime dueTime(schedule->DueTime());
   709 	TPBTime pDueTime(dueTime);
   710 	iClientMessage->WriteL(2, pDueTime);
   711 	}
   712 
   713 void CSchSession::GetTaskRefsL()
   714 	{
   715 	//taskrefs for all, 
   716 	//or just the ones I scheduled, 
   717 	//or just the pending ones, 
   718 	//or just the pending ones I scheduled
   719 	
   720 	TInt expectedCount = iClientMessage->GetIntL(0);
   721 	TScheduleFilter sFilter = STATIC_CAST(TScheduleFilter, iClientMessage->GetIntL(1));
   722 	TTaskFilter tFilter = STATIC_CAST(TTaskFilter, iClientMessage->GetIntL(2));
   723 	CArrayFixFlat<TSchedulerItemRef>* refs 
   724 		= new (ELeave) CArrayFixFlat<TSchedulerItemRef> (KSchedulerArrayGranularity);
   725 	CleanupStack::PushL(refs);
   726 	
   727 	//GetTaskRefs filters on clients schedule permssion as well.
   728 	TInt actualCount = iTaskScheduler->GetTaskRefsL(refs, sFilter, tFilter,iClient, iClientMessage->Message());
   729 	
   730 	// Must find enough tasks.
   731 	if((actualCount != expectedCount) || (refs->Count() == 0))
   732 		User::Leave(KErrArgument);
   733 	
   734 	// Write array back to client
   735 	TPtrC8 pR(REINTERPRET_CAST(TUint8*,&refs->At(0)),sizeof(TSchedulerItemRef)*expectedCount);
   736 	iClientMessage->WriteL(3, pR);
   737 	CleanupStack::PopAndDestroy();//refs
   738 	}
   739 
   740 void CSchSession::CountTasksL()
   741 	{
   742 	//count either all of 'em or just mine
   743 	
   744 	TScheduleFilter sFilter = STATIC_CAST(TScheduleFilter, iClientMessage->GetIntL(1));
   745 	TTaskFilter tFilter = STATIC_CAST(TTaskFilter, iClientMessage->GetIntL(2));
   746 
   747 	//GetTaskRefs filters on clients schedule permssion as well.
   748 	TInt count = iTaskScheduler->GetTaskRefsL(NULL, sFilter, tFilter,iClient, iClientMessage->Message());
   749 
   750 	TPInt pCount(count);
   751 	iClientMessage->WriteL(0,pCount);
   752 	}
   753 
   754 void CSchSession::GetTaskInfoL()
   755 	{
   756 	// Get task
   757 	TInt taskId				= iClientMessage->GetIntL(0);
   758 	TInt scheduleId			= (taskId/KScheduleIdDifferential)*KScheduleIdDifferential;
   759 	CSchedule* schedule		= iTaskScheduler->FindL(scheduleId);
   760 	
   761 	//check that user has permission to get this task info (based on owning 
   762 	//schedules info).
   763 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   764 	
   765 	TScheduledTask* task = schedule->Task(taskId);
   766 	if	(!task)
   767 		User::Leave(KErrNotFound);
   768 
   769 	TPBTaskInfo pI(task->Info());
   770 
   771 	iClientMessage->WriteL(1, pI);//write info	
   772 	
   773 	// If there isn't enough room to hold the task data in the client buffer then
   774 	// indicate by returning KErrArgument
   775 	TInt clientBufferSize = iClientMessage->GetIntL(2);
   776 	if	(clientBufferSize < task->Data().Length())
   777 		User::Leave(KErrArgument);
   778 	iClientMessage->WriteL(3, task->Data());
   779 	}
   780 
   781 void CSchSession::GetScheduleItemRefAndDueTimeL()
   782 	{
   783 	// Get CSchedule object
   784 	TInt taskId = iClientMessage->GetIntL(0);
   785 	TInt scheduleId = (taskId/KScheduleIdDifferential)*KScheduleIdDifferential;
   786 	CSchedule* schedule = iTaskScheduler->FindL(scheduleId);
   787 
   788 	//check that user has permission to get this schedules info.
   789 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   790 	
   791 	TSchedulerItemRef ref;
   792 	ref.iHandle	= schedule->Id();
   793 	ref.iName	= schedule->Name();
   794 
   795 	TPBSchedulerItemRef pRef(ref);
   796 	iClientMessage->WriteL(1, pRef);
   797 	
   798 	TTsTime dueTime(schedule->DueTime());
   799 	TPBTime pDueTime(dueTime);
   800 	iClientMessage->WriteL(2, pDueTime);
   801 	}
   802 
   803 void CSchSession::GetTaskDataSizeL()
   804 	{
   805 	TInt taskId = iClientMessage->GetIntL(0);
   806 	TInt scheduleId = (taskId/KScheduleIdDifferential)*KScheduleIdDifferential;
   807 	CSchedule* schedule = iTaskScheduler->FindL(scheduleId);
   808 
   809 	//check that user has permission to get this task info (based on owning 
   810 	//schedules info).
   811 	schedule->CheckAccessAllowedL(iClientMessage->Message());
   812 	
   813 	TScheduledTask* task = schedule->Task(taskId);
   814 	if	(!task)
   815 		User::Leave(KErrNotFound);
   816 
   817 	TInt size = task->Data().Length();
   818 	TPInt pSize(size);
   819 	iClientMessage->WriteL(1,pSize);
   820 	}
   821 
   822 void  CSchSession::CheckCapabilityL()
   823 	{
   824 	if( !( iClientMessage->Message().HasCapability(ECapabilityWriteDeviceData)
   825 		|| (PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement)==0 ))) // Enforcement off
   826 		User::Leave(KErrPermissionDenied);	
   827 	}
   828 	
   829 void CSchSession::CheckPersistsInBackupL(const CSchedule& aSchedule)
   830 	{
   831 	// backup or restore in progress, so don't allow functions that might write to store	
   832 	if ((iTaskScheduler->BUROperationInProgress() != EBUROperationNoActivity) && (aSchedule.Persists()))
   833 		{
   834 		User::Leave(KErrServerBusy);
   835 		}
   836 	}
   837