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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
23 #include <e32property.h>
24 #include <schinfointernal.h>
25 #include "TestUtils.h"
27 _LIT(KTestName, "Task Scheduler Condition Scheduling Test - UTC");
29 RTest TheTest(KTestName);
31 typedef CArrayFixFlat<TTaskInfo> CTaskInfoArray;
32 typedef CArrayFixFlat<TSchedulerItemRef> CSchItemRefArray;
33 typedef CArrayFixFlat<TTaskSchedulerCondition> CSchConditionArray;
35 static RScheduler TheScheduler;
36 static CTrapCleanup* TheCleanup;
37 static RFs TheFsSession;
39 const TInt KTestKey1 = 1;
40 const TInt KTestKey2 = 2;
41 const TInt KTestKey3 = 3;
43 _LIT(KMinimalTaskHandler, "MinimalTaskHandler");
44 _LIT(KSeparator, "|"); // Invalid filepath char used to separate filenames
46 // This function launches the TPropertyDefine process which
47 // has WriteDeviceData Capabilities enabling it to create the P&S
48 // variables used by this test.
49 static void LaunchHelperL(TUid aCategory, TInt aKey, TInt aAttr)
51 _LIT(KConditionHelper, "TPropertyDefine");
55 args.AppendNum(aCategory.iUid);
56 args.Append(KSeparator);
58 args.Append(KSeparator);
59 args.AppendNum(aAttr);
60 User::LeaveIfError(p.Create(KConditionHelper, args,EOwnerProcess));
62 // Asynchronous logon: completes when process terminates with process exit code
66 User::WaitForRequest(stat);
67 TInt exitReason = p.ExitReason();
69 User::LeaveIfError(exitReason);
71 static void CreateTestVariables()
73 LaunchHelperL(KUidSystemCategory, KTestKey1,RProperty::EInt);
74 LaunchHelperL(KUidSystemCategory, KTestKey2,RProperty::EInt);
75 LaunchHelperL(KUidSystemCategory, KTestKey3,RProperty::EInt);
78 static void ResetVariablesL(TInt aKey1Val,
82 User::LeaveIfError(RProperty::Set(KUidSystemCategory, KTestKey1,aKey1Val));
83 User::LeaveIfError(RProperty::Set(KUidSystemCategory, KTestKey2,aKey2Val));
84 User::LeaveIfError(RProperty::Set(KUidSystemCategory, KTestKey3,aKey3Val));
87 static void GetTaskInfoL(CTaskInfoArray& aTaskInfoArray,
89 // Extract schedule references from the schedule server based on a filter. If
91 aTaskInfoArray.Reset();
93 TScheduleState2 state;
94 CSchConditionArray* conditionList
95 = new (ELeave) CSchConditionArray(3);
96 CleanupStack::PushL(conditionList);
97 TInt res = TheScheduler.GetScheduleL(aScheduleId,
102 TEST2(res, KErrNone);
103 CleanupStack::PopAndDestroy(conditionList);
106 static TInt CountTasksL(TInt aScheduleId)
108 CTaskInfoArray* tasks = new (ELeave) CTaskInfoArray(3);
109 CleanupStack::PushL(tasks);
110 GetTaskInfoL(*tasks, aScheduleId);
111 TInt ret = tasks->Count();
112 CleanupStack::PopAndDestroy(tasks);
117 static TInt CountScheduledItemsL(TScheduleFilter aFilter,
118 RScheduler& aScheduler)
119 // Extract schedule references from the schedule server based on a filter. If
121 CSchItemRefArray* refs = new (ELeave) CSchItemRefArray(3);
122 CleanupStack::PushL(refs);
124 TInt res = aScheduler.GetScheduleRefsL(*refs, aFilter);
125 TEST2(res, KErrNone);
127 TInt count = refs->Count();
128 CleanupStack::PopAndDestroy(); // refs
132 static CSchConditionArray* CreateSingleConditionLC(const TUid& aConditionUID,
133 TUint aConditionUInt)
135 CSchConditionArray* conditionList = new (ELeave) CSchConditionArray(3);
136 CleanupStack::PushL(conditionList);
139 TTaskSchedulerCondition condition1;
140 condition1.iCategory = aConditionUID;
141 condition1.iKey = aConditionUInt;
142 condition1.iState = 10;
143 condition1.iType = TTaskSchedulerCondition::EEquals;
144 conditionList->AppendL(condition1);
146 return conditionList;
149 static CSchConditionArray* CreateMultipleConditionsLC()
151 CSchConditionArray* conditionList = new (ELeave) CSchConditionArray(3);
152 CleanupStack::PushL(conditionList);
154 TTaskSchedulerCondition condition1;
155 condition1.iCategory = KUidSystemCategory;
156 condition1.iKey = KTestKey1;
157 condition1.iState = 10;
158 condition1.iType = TTaskSchedulerCondition::EEquals;
159 conditionList->AppendL(condition1);
162 TTaskSchedulerCondition condition2;
163 condition2.iCategory = KUidSystemCategory;
164 condition2.iKey = KTestKey2;
165 condition2.iState = 10;
166 condition2.iType = TTaskSchedulerCondition::ENotEquals;
167 conditionList->AppendL(condition2);
170 TTaskSchedulerCondition condition3;
171 condition3.iCategory = KUidSystemCategory;
172 condition3.iKey = KTestKey3;
173 condition3.iState = 10;
174 condition3.iType = TTaskSchedulerCondition::ELessThan;
175 conditionList->AppendL(condition3);
177 return conditionList;
180 // single condition with default time set to 1 year in the future
181 // As this is a valid time a CTimer object actually gets set unlike
182 // if Time::TTimeMax() is used, hence we need to test for both cases.
183 static TInt CreateScheduleSingle1L(TSchedulerItemRef& aRef,
184 RScheduler& aScheduler,
185 const TUid& aConditionUID,
186 TUint aConditionUInt)
188 aRef.iName = _L("Schedule created using CreateScheduleSingle");
190 CSchConditionArray* conditionList
191 = CreateSingleConditionLC(aConditionUID, aConditionUInt);
193 TTime ttime(SchSvrHelpers::UtcTimeBasedOnOffset(0, 0, 0, 0, 0, 1));
194 TTsTime time(ttime, ETrue); //1 year in the future
195 TInt res = aScheduler.CreatePersistentSchedule(aRef, *conditionList, time);
196 CleanupStack::PopAndDestroy(); // conditionList
200 // single condition with default time set to Time::MaxTTime()
201 static TInt CreateScheduleSingle2L(TSchedulerItemRef& aRef,
202 RScheduler& aScheduler,
203 const TUid& aConditionUID,
204 TUint aConditionUInt)
206 aRef.iName = _L("Schedule created using CreateScheduleSingle");
208 CSchConditionArray* conditionList
209 = CreateSingleConditionLC(aConditionUID, aConditionUInt);
210 TTime ttime(Time::MaxTTime());
211 TTsTime time(ttime, ETrue);
212 TInt res = aScheduler.CreatePersistentSchedule(aRef, *conditionList, time);
213 CleanupStack::PopAndDestroy(); // conditionList
217 // An empty schedule list.
218 static TInt CreateScheduleEmpty3L(TSchedulerItemRef& aRef,
219 RScheduler& aScheduler,
223 aRef.iName = _L("Empty Schedule list created");
225 CSchConditionArray* conditionList = new (ELeave) CSchConditionArray(3);
226 CleanupStack::PushL(conditionList);
227 TTime ttime(SchSvrHelpers::UtcTimeBasedOnOffset(0, 0, 0, 0, 0, 1));
228 TTsTime time(ttime, ETrue); //1 year in the future
229 TInt res = aScheduler.CreatePersistentSchedule(aRef, *conditionList, time);
230 CleanupStack::PopAndDestroy(); // conditionList
236 static TInt CreateScheduleSingleNull4L(TSchedulerItemRef& aRef,
237 RScheduler& aScheduler,
241 aRef.iName = _L("One schedule in the list with a NULL uid");
243 CSchConditionArray* conditionList
244 = CreateSingleConditionLC(KNullUid, 0);
245 TTime ttime(SchSvrHelpers::UtcTimeBasedOnOffset(0, 0, 0, 0, 0, 1));
246 TTsTime time(ttime, ETrue); //1 year in the future
247 TInt res = aScheduler.CreatePersistentSchedule(aRef, *conditionList, time);
248 CleanupStack::PopAndDestroy(); // conditionList
253 static TInt CreateScheduleMultipleL(TSchedulerItemRef& aRef, RScheduler& aScheduler)
255 aRef.iName = _L("Schedule created using CreateScheduleMultiple");
257 CSchConditionArray* conditionList = CreateMultipleConditionsLC();
258 TTime ttime(SchSvrHelpers::UtcTimeBasedOnOffset(0, 0, 0, 0, 0, 1));
259 TTsTime time(ttime, ETrue); //1 year in the future
260 TInt res = aScheduler.CreatePersistentSchedule(aRef, *conditionList, time);
261 CleanupStack::PopAndDestroy(); // conditionList
265 static TInt SchedulePersistentTaskL(const TDesC& aName,
268 RScheduler& aScheduler)
271 taskInfo.iTaskId = aNewId;
272 taskInfo.iName = aName;
273 taskInfo.iPriority = 2;
274 taskInfo.iRepeat = 0;
275 HBufC* data = _L("the data").AllocLC();
276 TInt res = aScheduler.ScheduleTask(taskInfo, *data, aScheduleId);
277 aNewId = taskInfo.iTaskId;
279 CleanupStack::PopAndDestroy(); // data
285 @SYMTestCaseID SYSLIB-SCHSVR-CT-0244
286 @SYMTestCaseDesc Single condition based test - UTC
287 @SYMTestPriority High
288 @SYMTestActions Create a condition based schedule & check schedule auto deletes
289 @SYMTestExpectedResults The test must not fail.
292 static void DoTest1L()
294 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-0244 "));
295 // create a simple condition based schedule, and see if it runs.
297 TheTest.Next(_L("single condition based test"));
300 //reset the p&s variables before creating the schedule
301 ResetVariablesL(0,0,0);
302 TSchedulerItemRef ref1;
303 TheTest.Printf(_L("Create a schedule\n"));
304 res = CreateScheduleSingle1L(ref1, TheScheduler, KUidSystemCategory, KTestKey1);
305 TEST2(res, KErrNone);
308 _LIT(KName1, "toothpaste");
309 TheTest.Printf(_L("Schedule some tasks\n"));
311 res = SchedulePersistentTaskL(KName1, task1, ref1.iHandle, TheScheduler);
312 TEST2(res, KErrNone);
314 res = TheScheduler.__DbgMarkHeap();
315 User::LeaveIfError(res); //#1
316 TInt scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
317 TEST(scheduleCount == 1);
319 // Check that schedule is of condition type
320 TScheduleType scheduleType;
321 res = TheScheduler.GetScheduleTypeL(ref1.iHandle, scheduleType);
322 TEST2(res, KErrNone);
323 TEST(scheduleType == EConditionSchedule );
325 res = TheScheduler.__DbgMarkEnd(0);
326 User::LeaveIfError(res); //#1
328 TheScheduler.Close();
329 SchSvrHelpers::Pause(TheTest);
331 // wait for condition to be satisfied
332 res = RProperty::Set(KUidSystemCategory, KTestKey1,10);
333 User::LeaveIfError(res);
334 TEST2(STaskSemaphore::WaitL(KDefaultTimeout), KErrNone);
335 CleanupHelpers::KillProcess(KMinimalTaskHandler);
337 res = TheScheduler.Connect();
338 TEST2(res, KErrNone);
339 // Register a client with the server
340 TheTest.Next(_L("===== Registering Client ====="));
341 res = SchSvrHelpers::RegisterClientL(TheScheduler);
342 TEST2(res, KErrNone);
344 // can't check scheduler to see if any tasks left because it's been
345 // deleted as last task has completed
347 //Check that persistent schedule has auto-deleted
349 TheTest.Printf(_L("DEF46200 - Check schedule has auto deleted\n"));
350 scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
351 TEST(scheduleCount == 0);
353 // Attempt to delete auto-deleted schedule, should fail
355 TheTest.Printf(_L("DEF46200 - Attempting to delete schedule with id %d\n"), ref1.iHandle);
356 res = TheScheduler.DeleteSchedule(ref1.iHandle);
357 TEST2(res, KErrNotFound);
359 // now repeat process with singleschedule2
360 ResetVariablesL(0,0,0);
362 TheTest.Printf(_L("Create another schedule\n"));
363 res = CreateScheduleSingle2L(ref1, TheScheduler, KUidSystemCategory, KTestKey1);
364 TEST2(res, KErrNone);
366 TheTest.Printf(_L("Create an empty schedule list\n"));
367 res = CreateScheduleEmpty3L(ref1, TheScheduler, KUidSystemCategory, KTestKey1);
368 TEST2(res, KErrArgument);
370 TheTest.Printf(_L("Create an empty schedule list\n"));
371 res = CreateScheduleSingleNull4L(ref1, TheScheduler, KUidSystemCategory, KTestKey1);
372 TEST2(res, KErrArgument);
374 res = SchedulePersistentTaskL(KName1, task1, ref1.iHandle, TheScheduler);
375 TEST2(res, KErrNone);
376 SchSvrHelpers::Pause(TheTest);
378 // we should have one outstanding task (without the check in
379 // schtimer.cpp specifically for Time::MaxTTime() the timer would have
380 // gone off immediately in the past.)
381 TEST(CountTasksL(ref1.iHandle) == 1);
383 scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
384 TEST(scheduleCount == 1);
385 // wait for condition to be satisfied
386 User::LeaveIfError(RProperty::Set(KUidSystemCategory, KTestKey1,10));
387 TEST2(STaskSemaphore::WaitL(KDefaultTimeout), KErrNone);
388 CleanupHelpers::KillProcess(KMinimalTaskHandler);
390 // can't check scheduler to see if any tasks left because it's been
391 // deleted as last task has completed
393 TheTest.Printf(_L("DEF46200 - Check schedule has auto deleted\n"));
394 scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
395 TEST(scheduleCount == 0);
397 // Attempt to delete auto-deleted schedule, should fail
399 TheTest.Printf(_L("DEF46200 - Attempting to delete schedule with id %d\n"), ref1.iHandle);
400 res = TheScheduler.DeleteSchedule(ref1.iHandle);
401 TEST2(res, KErrNotFound);
403 SchSvrHelpers::Pause(TheTest);
409 @SYMTestCaseID SYSLIB-SCHSVR-CT-0245
410 @SYMTestCaseDesc Multiple condition based test - UTC
411 @SYMTestPriority High
412 @SYMTestActions Create a condition based schedule with multiple entries, and see if it runs.
413 Try auto deleting the last schedule and test for not found error.
414 @SYMTestExpectedResults The test must not fail.
417 static void DoTest2L()
419 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-0245 "));
420 // create a condition based schedule with multiple entries, and see if it runs.
422 TheTest.Next(_L("multiple condition based test"));
425 //reset the p&s variables before creating the schedule
426 ResetVariablesL(0,10,20);
427 TSchedulerItemRef ref1;
428 TheTest.Printf(_L("Create a schedule\n"));
429 res = CreateScheduleMultipleL(ref1, TheScheduler);
430 TEST2(res, KErrNone);
433 _LIT(KName1, "web subscription");
434 TheTest.Printf(_L("Schedule some tasks\n"));
435 res = SchedulePersistentTaskL(KName1, task1, ref1.iHandle, TheScheduler);
436 TEST2(res, KErrNone);
438 TInt scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
439 TEST(scheduleCount == 1);
441 // we should have one task scheduled to run
442 CTaskInfoArray* tasks = new (ELeave) CTaskInfoArray(3);
443 CleanupStack::PushL(tasks);
444 GetTaskInfoL(*tasks, ref1.iHandle);
445 TEST(tasks->Count() == 1);
448 // wait for conditions to be satisfied
449 User::LeaveIfError(RProperty::Set(KUidSystemCategory, KTestKey1,10));//"=="
450 User::LeaveIfError(RProperty::Set(KUidSystemCategory, KTestKey2,1234));//"!="
451 User::LeaveIfError(RProperty::Set(KUidSystemCategory, KTestKey3,9));//"<"
452 TEST2(STaskSemaphore::WaitL(KDefaultTimeout), KErrNone);
453 CleanupHelpers::KillProcess(KMinimalTaskHandler);
455 // Can't check schedule for task info because it's gone
458 // we should have no schedule, it has auto-deleted
459 scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
460 TEST(scheduleCount == 0);
463 TheTest.Printf(_L("Reseting variables"));
464 ResetVariablesL(0,10,20);
466 TheTest.Printf(_L("DEF46200 - Attempting to delete schedule with id %d\n"), ref1.iHandle);
467 res = TheScheduler.DeleteSchedule(ref1.iHandle);
468 TEST2(res, KErrNotFound);
469 scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
470 TEST(scheduleCount == 0);
472 CleanupStack::PopAndDestroy(tasks);
474 SchSvrHelpers::Pause(TheTest);
480 @SYMTestCaseID SYSLIB-SCHSVR-CT-0246
481 @SYMTestCaseDesc Error checking test - UTC
482 @SYMTestPriority High
483 @SYMTestActions Create a schedule with a P&S variables that doesnt exist & create a schedule with a P&S variable that isnt an integer.
484 @SYMTestExpectedResults The test must not fail.
487 static void DoTest3L()
489 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-0246 "));
490 // create a simple condition based schedule, and see if it runs.
492 TheTest.Next(_L("error checking test"));
495 //reset the p&s variables before creating the schedule
496 ResetVariablesL(0,0,0);
497 TSchedulerItemRef ref1;
498 _LIT(KName1, "toothpaste");
500 TheTest.Printf(_L("Create a schedule with a P&S variables that doesnt exist\n"));
502 const TUid KNonexistentUid = TUid::Uid(0x01234566);
503 res = CreateScheduleSingle1L(ref1, TheScheduler, KNonexistentUid, KTestKey1);
504 TEST2(res, KErrNone);
505 TheTest.Printf(_L("Schedule some tasks - error should be returned\n"));
508 taskInfo.iName = KName1;
509 taskInfo.iPriority = 2;
510 taskInfo.iRepeat = 0;
511 HBufC* data = _L("the data").AllocLC();
512 res = TheScheduler.ScheduleTask(taskInfo, *data, ref1.iHandle);
513 // since we have created the schedule using a UID which doesn't exist
514 //we should get an error
515 TEST2(res, KErrArgument);
516 CleanupStack::PopAndDestroy(); // data
518 TheTest.Printf(_L("Deleting schedule with id %d\n"), ref1.iHandle);
519 res = TheScheduler.DeleteSchedule(ref1.iHandle);
520 TEST2(res, KErrNone);
521 TInt scheduleCount = CountScheduledItemsL(EAllSchedules, TheScheduler);
522 TEST(scheduleCount == 0);
525 TheTest.Printf(_L("Create a schedule\n"));
526 res = CreateScheduleSingle1L(ref1, TheScheduler, KUidSystemCategory, KTestKey1);
527 TEST2(res, KErrNone);
528 TheTest.Printf(_L("Schedule some tasks\n"));
531 taskInfo.iName = KName1;
532 taskInfo.iPriority = 2;
533 taskInfo.iRepeat = 1;
534 HBufC* data = _L("the data").AllocLC();
535 User::LeaveIfError(TheScheduler.__DbgMarkHeap());
536 res = TheScheduler.ScheduleTask(taskInfo, *data, ref1.iHandle);
537 // since we have set repeat to something other than 0, we should get an error
538 TEST2(res, KErrArgument);
539 User::LeaveIfError(TheScheduler.__DbgMarkEnd(0));
540 CleanupStack::PopAndDestroy(); // data
543 SchSvrHelpers::Pause(TheTest);
548 @SYMTestCaseID SYSLIB-SCHSVR-CT-3245
549 @SYMTestCaseDesc Persistent condition based schedule test
550 @SYMTestPriority High
551 @SYMTestActions Create a single persistent condition based schedule and then
552 terminate the task scheduler.
553 Set the condition and then launch the task scheduler with the
554 condition satisfied. Check that the schedule is executed.
555 @SYMTestExpectedResults Schedule must be executed and test must not panic or fail
558 static void DoTest4L()
560 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-3245 "));
561 // create a persistent condition based schedule
563 TheTest.Next(_L("single condition based test"));
566 //reset the p&s variables before creating the schedule
567 ResetVariablesL(0,0,0);
568 TSchedulerItemRef ref1;
569 TheTest.Printf(_L("Create a test schedule\n"));
570 res = CreateScheduleSingle1L(ref1, TheScheduler, KUidSystemCategory, KTestKey1);
571 TEST2(res, KErrNone);
574 _LIT(KName1, "shutdown task 1");
575 TheTest.Printf(_L("Schedule a persistant task\n"));
577 res = SchedulePersistentTaskL(KName1, task1, ref1.iHandle, TheScheduler);
578 TEST2(res, KErrNone);
580 //Fault the server to force it to shut down
581 TheScheduler.__FaultServer();
583 //close the Scheduler handle
584 TheScheduler.Close();
586 SchSvrHelpers::Pause(TheTest);
589 res = RProperty::Set(KUidSystemCategory, KTestKey1,10);
590 TEST2(res, KErrNone);
592 //Restart the scheduler with the condition for this persistant task
594 res = TheScheduler.Connect();
595 TEST2(res, KErrNone);
597 //wait for task to be executed
598 TEST2(STaskSemaphore::WaitL(KDefaultTimeout), KErrNone);
599 CleanupHelpers::KillProcess(KMinimalTaskHandler);
601 SchSvrHelpers::Pause(TheTest);
607 static TInt RunTestsL()
609 TheTest.Next(_L("Delete old files"));
610 SchSvrHelpers::DeleteScheduleFilesL();
612 TheTest.Next(_L("Create Task notification semaphore"));
613 //initialise task notification semaphore
617 // Connect to the server
618 TheTest.Next(_L("===== Connect to Scheduler ====="));
619 TInt res = TheScheduler.Connect();
620 TEST2(res, KErrNone);
621 // Register a client with the server
622 TheTest.Next(_L("===== Registering Client ====="));
623 res = SchSvrHelpers::RegisterClientL(TheScheduler);
624 TEST2(res, KErrNone);
626 // Launch helper process to create P&S variables
627 CreateTestVariables();
629 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
630 CleanupStack::PushL(scheduler);
631 CActiveScheduler::Install(scheduler);
633 TheTest.Next(_L("Start tests"));
639 TheTest.Next(_L("Tidying up"));
640 CleanupStack::PopAndDestroy(scheduler);
641 //close handle to semaphore
644 //Tidying up so next test will be clear.
645 TheTest.Next(_L("Delete all schedules"));
646 SchSvrHelpers::DeleteAllSchedulesL(TheScheduler);
647 SchSvrHelpers::Pause(TheTest, 2);
648 TheTest.Next(_L("Delete old files\n"));
649 SchSvrHelpers::DeleteScheduleFilesL();
651 TheScheduler.Close();
655 GLDEF_C TInt E32Main()
658 TheTest.Start(_L("TC_TSCH_CONDITION_UTC"));
660 TheCleanup = CTrapCleanup::New();
662 //If the previous test fails, SCHSVR.exe may stay in memory.
663 TRAPD(error,CleanupHelpers::TestCleanupL());
664 TEST2(error, KErrNone);
665 TheTest(TheFsSession.Connect() == KErrNone);;
666 TRAP(error, RunTestsL());
667 TEST2(error, KErrNone);
668 TRAP(error,CleanupHelpers::TestCleanupL());
669 TEST2(error, KErrNone);
672 TheFsSession.Close();