Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32test\server\t_notify.cpp
//
//
#include <f32file.h>
#include <e32test.h>
#include <e32svr.h>
#include <hal.h>
#include "t_server.h"
const TInt KHeapSize=0x200;
// wait for a bit since NotifyChange handled asynchronously and SetDriveName synchronously
const TInt KNotifyChangeAfter=100000;
const TInt KMediaRemountForceMediaChange = 0x00000001;
RTest test(_L("T_NOTIFY"));
RSemaphore gSleepThread;
TInt gSocketNumber=0;
TInt SocketToDrive[KMaxPBusSockets];
//#define __INCLUDE_MANUAL_TESTS__
void do_check_no_pending_requests(TInt aLine)
{
RTimer timer;
TRequestStatus timerStat;
timer.CreateLocal();
timer.After(timerStat, 125000);
User::WaitForAnyRequest();
if(timerStat==KRequestPending)
{
RDebug::Printf("do_check_no_pending_requests failed at line %d",aLine);
test(0);
}
timer.Close();
}
#define CHECK_NO_PENDING_REQUESTS do_check_no_pending_requests(__LINE__);
TBool CheckDriveRead(TInt aDrive)
//Determines if can connect to local drive number and read
{
TBusLocalDrive TBLD;
TBool TBLDChangedFlag;
TInt r = TBLD.Connect(aDrive, TBLDChangedFlag);
test.Printf(_L("Connect returned %d\n"), r);
if (r == KErrNone)
{
const TInt KSectSize = 512;
TBuf8<KSectSize> sect;
r = TBLD.Read(0, KSectSize, sect);
test.Printf(_L("Read returned %d\n"), r);
TBLD.Disconnect();
if(r!=KErrNone)
return EFalse;
else
return ETrue;
}
else
return EFalse;
}
void GenerateMediaChange()
{
TPckgBuf<TInt> pckg;
pckg()=0;
RFs fs;
TInt r = fs.Connect();
if (r == KErrNone)
{
r = fs.RemountDrive(CurrentDrive(), &pckg, (TUint)KMediaRemountForceMediaChange);
if(r == KErrNotReady)
{
r = KErrNone;
}
fs.Close();
}
if (r!=KErrNone)
{
RProcess me;
me.Panic(_L("GenMedChg"),r);
}
}
enum TTestCode {ETest1,ETest2,ETest3,ETest4,ETest5,ETest6,ETest7,ETest8,ETest9,ETest10,ETest11,ETest12};
const TUint KGenericEntryChange=0x02;
static TInt ThreadEntryPoint(TAny* aTestCode)
//
// Thread entry point
//
{
RFs fs;
TInt r=fs.Connect();
test(r==KErrNone);
r=fs.SetSessionPath(gSessionPath);
test(r==KErrNone);
TTestCode testCode=*(TTestCode*)&aTestCode;
RFile f;
switch (testCode)
{
case ETest1:
r=f.Replace(fs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileStream);
test(r==KErrNone);
f.Close();
break;
case ETest2:
r=f.Replace(fs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileStream);
test(r==KErrNone);
f.Close();
break;
case ETest3:
r=fs.MkDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\SCARECROW\\"));
test((r==KErrNone)||(r==KErrAlreadyExists));
break;
case ETest4:
{
TRequestStatus s;
fs.NotifyChange(ENotifyAll,s);
test(s==KRequestPending);
gSleepThread.Signal();
User::After(100000000);
}
break;
case ETest5:
{
RFile file;
TInt r=file.Open(fs,_L("\\F32-TST\\NOTIFY\\kangaroo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
r=file.SetSize(sizeof(TCheckedUid));
test(r==KErrNone);
r=file.Write(sizeof(TCheckedUid),_L8("012345678912"));
test(r==KErrNone);
TBuf8<64> dum;
r=file.Read(0,dum);
test(r==KErrNone);
file.Close();
r=file.Open(fs,_L("\\F32-TST\\NOTIFY\\koala.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
r=file.SetSize(50);
test(r==KErrNone);
r=file.Write(sizeof(TCheckedUid),_L8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
test(r==KErrNone);
r=file.Read(0,dum);
test(r==KErrNone);
file.Close();
r=file.Open(fs,_L("\\F32-TST\\NOTIFY\\dingo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
r=file.SetSize(50);
test(r==KErrNone);
r=file.Write(sizeof(TCheckedUid),_L8("01234567890123456789"));
test(r==KErrNone);
r=file.Read(0,dum);
test(r==KErrNone);
file.Close();
gSleepThread.Signal();
}
break;
case ETest6:
{
GenerateMediaChange();
User::After(300000); // Wait for a bit
gSleepThread.Signal();
}
break;
case ETest7:
{
RFile file;
TInt r=file.Open(fs,_L("\\F32-TST\\NOTIFY\\NewFILE.TXT"),EFileRead|EFileWrite);
test(r==KErrNone);
r=file.Write(_L8("asdfasdfasdf"));
test(r==KErrNone);
file.Close();
gSleepThread.Signal();
}
break;
case ETest8:
{
r=f.Open(fs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\WickedWitch.msg"),EFileRead|EFileWrite);
test(r==KErrNone);
f.SetSize(500);
f.Close();
break;
}
case ETest9:
{
TRequestStatus s;
TFileName path=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,s,path);
test(s==KRequestPending);
gSleepThread.Signal();
User::After(100000000);
}
break;
case ETest10:
{
TFileName path=_L("\\F32-TST\\NOTIFY\\BehindTheCurtain\\");
r=fs.MkDir(path);
test(r==KErrNone);
break;
}
case ETest11:
{
TFileName path=_L("\\F32-TST\\NOTIFY\\BehindTheCurtain\\PayNoAttention.man");
RFile file;
r=file.Replace(fs,path,EFileStream);
test(r==KErrNone);
file.Close();
break;
}
case ETest12:
{
RFile writer;
TInt r=writer.Open(fs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileWrite|EFileShareAny);
test(r==KErrNone);
TInt i;
for(i=0; i<10; i++)
{
r=writer.Write(_L8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
test(r==KErrNone);
User::After(1000000);
}
writer.Close();
break;
}
default:
break;
}
return KErrNone;
}
#if defined (__EPOC32__)//we have no removable media on Emulator yet
static void WaitForMediaChange()
//
// Wait for media driver to register drive is present
//
{
TEntry entry;
FOREVER
{
User::After(10000);
TInt r=TheFs.Entry(_L("xxxxxxxx"),entry);
if (r!=KErrNotReady)
break;
}
}
#endif
static void Test1()
//
// Test notification of an entry change
//
{
test.Next(_L("Test notification of an entry change"));
TRequestStatus reqStat(KRequestPending);
TRequestStatus thrdStat(KRequestPending);
TInt r;
TheFs.NotifyChange(ENotifyEntry,reqStat);
RThread thread;
r=thread.Create(_L("MyThread"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest1);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
thread.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
RFile file;
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileWrite|EFileShareExclusive);
test(r==KErrNone);
file.Write(_L8("Somewhere over the rainbow..."),reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
TBuf8<256> buf;
file.Read(0, buf,reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileShareExclusive);
test(r==KErrArgument);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileShareReadersOnly);
test(r==KErrArgument);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileShareAny);
test(r==KErrNone);
file.Read(0, buf, 100, reqStat);
test(reqStat==KRequestPending);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileShareAny);
test(r==KErrNone);
file.Read(0, buf, 100, reqStat);
test(reqStat==KRequestPending);
file.ReadCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
file.Close();
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileWrite|EFileShareAny);
test(r==KErrNone);
file.Read(0, buf, 100, reqStat);
test(reqStat==KRequestPending);
file.SetSize(100);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
test(buf.Length() == 100);
file.Close();
test.Next(_L("Repeat Test notification of an entry change"));
TheFs.NotifyChange(ENotifyEntry,reqStat);
thread.Create(_L("MyThread2"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest1);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
thread.Close();
User::WaitForRequest(reqStat);
if (reqStat!=KErrNone)
{
test.Printf(_L("ReqStat=%d\n"),reqStat.Int());
//test.Getch();
}
test(reqStat==KErrNone);
test.Next(_L("Test Notify cancel"));
TheFs.NotifyChange(ENotifyEntry,reqStat);
TheFs.NotifyChangeCancel();
User::WaitForRequest(reqStat);
test.Next(_L("Test notification still works"));
TheFs.NotifyChange(ENotifyEntry,reqStat);
thread.Create(_L("MyThread3"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest1);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
thread.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
}
static void Test2()
//
// Test notify for multiple clients
//
{
test.Next(_L("Test notification of multiple clients"));
TRequestStatus reqStat1(KRequestPending);
RFs fs1;
TInt r=fs1.Connect();
test(r==KErrNone);
fs1.NotifyChange(ENotifyEntry,reqStat1);
TRequestStatus reqStat2(KRequestPending);
RFs fs2;
r=fs2.Connect();
test(r==KErrNone);
fs2.NotifyChange(ENotifyEntry,reqStat2);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\NEWFILE.TXT"));
test(r==KErrNone);
User::WaitForRequest(reqStat1);
User::WaitForRequest(reqStat2);
test(reqStat1==KErrNone);
test(reqStat2==KErrNone);
}
static void Test3()
//
// Test notify cancel
//
{
test.Next(_L("Cancel notification"));
RFs fs1;
TInt r=fs1.Connect();
test(r==KErrNone);
TRequestStatus status1;
TRequestStatus status2;
TRequestStatus status3;
TRequestStatus status4;
TRequestStatus status5;
fs1.NotifyChange(ENotifyAll,status1);
fs1.NotifyChange(ENotifyAll,status2);
fs1.NotifyChange(ENotifyAll,status3);
fs1.NotifyChange(ENotifyAll,status4);
fs1.NotifyChange(ENotifyAll,status5);
test(status1==KRequestPending);
test(status2==KRequestPending);
test(status3==KRequestPending);
test(status4==KRequestPending);
test(status5==KRequestPending);
test.Next(_L("RFs::NotifyCancel()"));
// Test that one call to RFs::NotifyCancel() cancels all outstanding requests
fs1.NotifyChangeCancel();
User::WaitForRequest(status1);
test(status1==KErrCancel);
User::WaitForRequest(status2);
test(status2==KErrCancel);
User::WaitForRequest(status3);
test(status3==KErrCancel);
User::WaitForRequest(status4);
test(status4==KErrCancel);
User::WaitForRequest(status5);
test(status5==KErrCancel);
// Call the cancel function again to check no further action
fs1.NotifyChangeCancel();
// Test overloaded function to cancel a single request
test.Next(_L("Cancel notification request using function overload"));
fs1.NotifyChange(ENotifyAll,status1);
fs1.NotifyChange(ENotifyAll,status2);
fs1.NotifyChange(ENotifyAll,status3);
fs1.NotifyChange(ENotifyAll,status4);
fs1.NotifyChange(ENotifyAll,status5);
test(status1==KRequestPending);
test(status2==KRequestPending);
test(status3==KRequestPending);
test(status4==KRequestPending);
test(status5==KRequestPending);
// Cancel the outstanding request with status5
test.Next(_L("RFs::NotifyCancel()"));
fs1.NotifyChangeCancel(status5);
User::WaitForRequest(status5);
test(status1==KRequestPending);
test(status2==KRequestPending);
test(status3==KRequestPending);
test(status4==KRequestPending);
test(status5==KErrCancel);
fs1.NotifyChangeCancel(status2);
User::WaitForRequest(status2);
test(status1==KRequestPending);
test(status2==KErrCancel);
test(status3==KRequestPending);
test(status4==KRequestPending);
fs1.NotifyChangeCancel(status4);
User::WaitForRequest(status4);
test(status1==KRequestPending);
test(status3==KRequestPending);
test(status4==KErrCancel);
fs1.NotifyChangeCancel(status4); // Test no side effects on trying to cancel a request
test(status4==KErrCancel); // that has already been cancelled
fs1.NotifyChangeCancel(status1);
User::WaitForRequest(status1);
test(status1==KErrCancel);
test(status3==KRequestPending);
fs1.NotifyChangeCancel(status1); // Test no side effects on trying to cancel a request
test(status1==KErrCancel); // that has already been cancelled
fs1.NotifyChangeCancel(status3);
User::WaitForRequest(status3);
test(status3==KErrCancel);
fs1.Close();
}
static void Test4()
//
// Test notify client death
//
{
test.Next(_L("Kill client"));
TInt r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread clientThread;
r=clientThread.Create(_L("ClientThread"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest4);
if (r!=KErrNone)
{
test.Printf(_L(" ERROR: Failed to create clientthread %d\n"),r);
test(0);
//test.Getch();
return;
}
clientThread.Resume();
gSleepThread.Wait();
TBool jit = User::JustInTime();
User::SetJustInTime(EFalse);
clientThread.Panic(_L("Test client thread panic"),KErrGeneral);
User::SetJustInTime(jit);
clientThread.Close();
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\"));
test(r==KErrNone || r==KErrAlreadyExists);
MakeFile(_L("\\F32-TST\\NOTIFY\\NewFile.Txt"));
User::After(1000);
}
static void Test5()
//
// Test reads and writes do not cause notification
//
{
test.Next(_L("Test reads and writes do not cause notification"));
RFile file;
TInt r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\kangaroo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\koala.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\dingo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
TRequestStatus reqStat=0;
TheFs.NotifyChange(ENotifyEntry,reqStat);
test(reqStat==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread clientThread;
r=clientThread.Create(_L("Test5Thread"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest5);
test(r==KErrNone);
clientThread.Resume();
gSleepThread.Wait();
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\kangaroo.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\koala.txt"));
test(r==KErrNone);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\dingo.txt"));
test(r==KErrNone);
gSleepThread.Close();
clientThread.Close();
}
#if defined (__EPOC32__)//we have no removable media on Emulator yet .. ??? we do now
static void Test6()
//
// Test media change notification
//
{
TDriveInfo driveInfo;
TInt r=TheFs.Drive(driveInfo,CurrentDrive());
test(r==KErrNone);
// only test on removable media
if (driveInfo.iDriveAtt&KDriveAttRemovable)
{
TBuf<64> b;
b.Format(_L("Test Media change notification (socket:%d)"),gSocketNumber);
test.Next(b);
TRequestStatus reqStat=0;
TInt r;
TheFs.NotifyChange(ENotifyEntry,reqStat);
test(reqStat==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread clientThread;
r=clientThread.Create(_L("Test6Thread"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest6);
test(r==KErrNone);
clientThread.Resume();
gSleepThread.Wait();
TInt reqInt=reqStat.Int();
test(reqInt==KErrNone);
User::WaitForRequest(reqStat);
WaitForMediaChange();
gSleepThread.Close();
clientThread.Close();
}
//-- it seems that after generating media change the meia driver isn't ready for some time
User::After(2000000);
r=TheFs.Drive(driveInfo,CurrentDrive());
test(r==KErrNone);
}
#endif
static void Test7()
//
// Test Write to uid region does not trigger notification
//
{
test.Next(_L("Test Write to uid region does not trigger notification"));
TRequestStatus reqStat=0;
MakeFile(_L("NewFile.TXT"));
TInt r;
TheFs.NotifyChange(ENotifyEntry,reqStat);
test(reqStat==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread clientThread;
r=clientThread.Create(_L("Test7Thread"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest7);
test(r==KErrNone);
clientThread.Resume();
gSleepThread.Wait();
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("Newfile.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
gSleepThread.Close();
clientThread.Close();
}
#if defined (__EPOC32__)//we have no removable media on Emulator yet
static void MediaChangeExtendedNotification()
//
// Test media change notification
// Always notified of media change - regardless of requested TNotifyType
//
{
TDriveInfo driveInfo;
TInt r=TheFs.Drive(driveInfo,CurrentDrive());
test(r==KErrNone);
// only test on removable media
if (driveInfo.iDriveAtt&KDriveAttRemovable)
{
test.Next(_L("Test Media change extended notification"));
TRequestStatus reqStat=0;
TFileName path = _L("\\F32-tst\\NOTIFY\\");
TInt r;
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread clientThread;
gSocketNumber=0;
r=clientThread.Create(_L("Test6Thread1"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest6); //only generates a media change on removable media
test(r==KErrNone);
clientThread.Resume();
gSleepThread.Wait();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
WaitForMediaChange();
gSleepThread.Close();
clientThread.Close();
//-- it seems that after generating media change the meia driver isn't ready for some time
User::After(2000000);
r=TheFs.Drive(driveInfo,CurrentDrive());
test(r==KErrNone);
TheFs.NotifyChange(ENotifyDisk,reqStat,path);
test(reqStat==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
r=clientThread.Create(_L("Test6Thread2"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest6);
test(r==KErrNone);
clientThread.Resume();
gSleepThread.Wait();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
WaitForMediaChange();
gSleepThread.Close();
clientThread.Close();
//-- it seems that after generating media change the meia driver isn't ready for some time
User::After(2000000);
r=TheFs.Drive(driveInfo,CurrentDrive());
test(r==KErrNone);
TheFs.NotifyChange(ENotifyWrite,reqStat,path);
test(reqStat==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
r=clientThread.Create(_L("Test6Thread3"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest6);
test(r==KErrNone);
clientThread.Resume();
gSleepThread.Wait();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
WaitForMediaChange();
gSleepThread.Close();
clientThread.Close();
//-- it seems that after generating media change the meia driver isn't ready for some time
User::After(2000000);
r=TheFs.Drive(driveInfo,CurrentDrive());
test(r==KErrNone);
}
}
#endif
static void TestRequestAhead()
//
// Test extended notification works when path initially does not exist
//
{
test.Next(_L("Test Request Ahead"));
// First a simple example
TInt r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\BehindTheCurtain\\"));
test((r==KErrNotFound)||(r==KErrPathNotFound)||(r==KErrNone));
TFileName path=_L("\\F32-TST\\NOTIFY\\BehindTheCurtain\\");
TRequestStatus reqStat(KRequestPending);
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\BehindTheCurtain\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
path=_L("\\F32-TST\\NOTIFY\\BehindTheCurtain\\PayNoAttention.man");
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
RFile file;
r=file.Replace(TheFs,path,EFileStream);
test(r==KErrNone);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Delete(path);
test(r==KErrNone);
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
// Now cancel the outstanding request
TheFs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Repeat with a ENotifyFile request
TheFs.NotifyChange(ENotifyFile,reqStat,path);
test(reqStat==KRequestPending);
r=file.Replace(TheFs,path,EFileStream);
test(r==KErrNone);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Delete(path);
test(r==KErrNone);
TheFs.NotifyChange(ENotifyFile,reqStat,path);
test(reqStat==KRequestPending);
// Now cancel the outstanding request
TheFs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Repeat with an ENotifyAttributes request
TheFs.NotifyChange(ENotifyAttributes,reqStat,path);
test(reqStat==KRequestPending);
r=file.Replace(TheFs,path,EFileStream);
test(r==KErrNone);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone); // Monitoring attributes but informed anyway
r=TheFs.Delete(path);
test(r==KErrNone);
TheFs.NotifyChange(ENotifyAttributes,reqStat,path);
test(reqStat==KRequestPending);
// Now cancel the outstanding request
TheFs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Repeat with an ENotifyWrite request
TheFs.NotifyChange(ENotifyWrite,reqStat,path);
test(reqStat==KRequestPending);
r=file.Replace(TheFs,path,EFileStream);
test(r==KErrNone);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone); // Monitoring file writing but informed anyway
r=TheFs.Delete(path);
test(r==KErrNone);
TheFs.NotifyChange(ENotifyWrite,reqStat,path);
test(reqStat==KRequestPending);
// Now cancel the outstanding request
TheFs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Repeat with an ENotifyDisk request
TheFs.NotifyChange(ENotifyDisk,reqStat,path);
test(reqStat==KRequestPending);
r=file.Replace(TheFs,path,EFileStream);
test(r==KErrNone);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone); // Monitoring disk activity but informed anyway
r=TheFs.Delete(path);
test(r==KErrNone);
TheFs.NotifyChange(ENotifyAttributes,reqStat,path);
test(reqStat==KRequestPending);
// Now cancel the outstanding request
TheFs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Now do much the same with directory monitoring
path=_L("\\F32-TST\\NOTIFY\\BehindTheCurtain\\");
TheFs.RmDir(path);
TheFs.NotifyChange(ENotifyDir,reqStat,path);
test(reqStat==KRequestPending);
TheFs.MkDir(path);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
TheFs.RmDir(path);
test(r==KErrNone);
TheFs.NotifyChange(ENotifyDir,reqStat,path);
test(r==KErrNone);
test(reqStat==KRequestPending);
// Now cancel the outstanding request
TheFs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
TheFs.NotifyChange(ENotifyDir,reqStat,path);
test(r==KErrNone);
test(reqStat==KRequestPending);
// Get a separate thread to create the directory
RThread thread;
thread.Create(_L("RequestAheadyThready"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest10);
TRequestStatus thrdStat(KRequestPending);
thread.Logon(thrdStat);
thread.Resume();
thread.Close();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
TheFs.RmDir(path);
test(r==KErrNone);
// Check that notification is not received for a non-existent file if only the previously
// non existent directory that contains it is created
path=_L("\\F32-TST\\NOTIFY\\BehindTheCurtain\\PayNoAttention.man");
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(r==KErrNone);
test(reqStat==KRequestPending);
thread.Create(_L("RequestAheadThread"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest10);
thread.Logon(thrdStat);
thread.Resume();
thread.Close();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
test(reqStat==KRequestPending);
// Now get a thread to create the file
thread.Create(_L("RequestAhead"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest11);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
thread.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
TheFs.Delete(path);
test(r==KErrNone);
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(r==KErrNone);
test(reqStat==KRequestPending);
// Now cancel the outstanding request
TheFs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
path=_L("\\F32-TST\\NOTIFY\\BehindTheCurtain\\");
TheFs.RmDir(path);
test(r==KErrNone);
}
static void Test8()
//
// Test extended notification of an entry change
//
{
// Test notification of an entry change in directory F32-TST
test.Next(_L("Test notification of an entry change"));
TRequestStatus reqStat(KRequestPending);
TRequestStatus thrdStat(KRequestPending);
TFileName path=(_L("\\F32-TST\\"));
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
RThread thread;
TInt r=thread.Create(_L("MyThread"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest1);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
thread.Close();
// Repeat the test
test.Next(_L("Repeat Test notification of an entry change"));
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=thread.Create(_L("MyThread2"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest1);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
thread.Close();
// Test it can be cancelled
test.Next(_L("Test Notify cancel"));
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
TheFs.NotifyChangeCancel();
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Test it can be notified again
test.Next(_L("Test notification still works"));
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=thread.Create(_L("MyThread3"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest1);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
thread.Close();
// Test notification doesn't occur when a change occurs above the directory monitored
// (Notification of rename events occurring above the directory which affect the path
// will occur - this is tested for in Test18())
test.Next(_L("Test changing above monitored directory"));
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\"));
test((r==KErrNone)||(r==KErrAlreadyExists));
path=_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\");
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=thread.Create(_L("MyThread4"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest1);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::After(500000);
thread.Close();
test(reqStat==KRequestPending);
TheFs.NotifyChangeCancel();
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Test notification occurs when a change is made to the subdirectory monitored
test.Next(_L("Create a file in monitored subdirectory"));
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=thread.Create(_L("MyThread5"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest2);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
thread.Close();
test.Next(_L("Create a directory in monitored subdirectory"));
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=thread.Create(_L("MyThread6"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest3);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
thread.Close();
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\SCARECROW\\TINMAN\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\SCARECROW\\TINMAN\\"));
test(r==KErrNone);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\SCARECROW\\"));
test(r==KErrNone);
// Test again that notification doesn't occur above the subdirectory being monitored
test.Next(_L("Test changing above monitored directory"));
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\"));
test((r==KErrNone)||(r==KErrAlreadyExists));
path=_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\");
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=thread.Create(_L("MyThread7"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest1);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::After(500000);
thread.Close();
test(reqStat==KRequestPending);
TheFs.NotifyChangeCancel();
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Test notification occurs when a change is made to the subdirectory monitored
test.Next(_L("Delete a file in monitored subdirectory"));
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
RFile file;
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\WickedWitch.msg"),EFileStream);
test(r==KErrNone);
file.Close();
// Test notification on a specific file
test.Next(_L("Monitor changes to a specific file"));
path+=_L("WickedWitch.msg");
TheFs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=thread.Create(_L("MyThread8"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest8);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
thread.Close();
// Test notification does not occur if a change is made above the file
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
thread.Create(_L("MyThread9"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest2);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::After(500000);
thread.Close();
test(reqStat==KRequestPending);
TheFs.NotifyChangeCancel();
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Test notification occurs when a change is made to the file
test.Next(_L("Delete monitored file"));
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\WickedWitch.Msg"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// Test notification request is now submitted on the non existent path successfully
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
TheFs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
path=_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.Doc");
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.Doc"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
path=_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\");
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// Submit a request for a path which does not yet exist
path=_L("\\F32-TST\\NOTIFY\\GOOD_WITCH\\");
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
// Now create the directory we are waiting on
r=TheFs.MkDir(path);
test(r==KErrNone);
// Make sure the notification has now been received
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// Submit a request for a file which does not yet exist
path=_L("\\F32-TST\\NOTIFY\\GOOD_WITCH\\Red-Shoes.red");
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
// Now create the file we are waiting on
r=file.Replace(TheFs,path,EFileStream);
test(r==KErrNone);
file.Close();
// Make sure the notification has now been received
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// Submit another notification request and delete the file
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(path);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
path=_L("\\F32-TST\\NOTIFY\\GOOD_WITCH\\");
TheFs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.RmDir(path);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// test passing in an empty string
TheFs.NotifyChange(ENotifyEntry,reqStat,_L(""));
User::WaitForRequest(reqStat);
test(reqStat==KErrArgument);
}
static void Test9()
//
// Test notify for multiple clients
//
{
test.Next(_L("Test notification of multiple clients"));
// Create five sessions monitoring various levels of a directory tree
TInt r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\ANIMAL\\"));
test((r==KErrNone)||(r==KErrAlreadyExists));
RFile file;
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\ANIMAL\\cat.txt"),EFileStream);
test(r==KErrNone);
file.Close();
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\ANIMAL\\dog.txt"),EFileStream);
test(r==KErrNone);
file.Close();
TFileName path1=_L("\\F32-TST\\");
TFileName path2=_L("\\F32-TST\\NOTIFY\\");
TFileName path3=_L("\\F32-TST\\NOTIFY\\ANIMAL\\");
TFileName path4=_L("\\F32-TST\\NOTIFY\\ANIMAL\\cat.txt");
TFileName path5=_L("\\F32-TST\\NOTIFY\\ANIMAL\\dog.txt");
TFileName path6=_L("?:\\F32-TST\\");
TRequestStatus reqStat1(KRequestPending);
RFs fs1;
r=fs1.Connect();
test(r==KErrNone);
r=fs1.SetSessionPath(gSessionPath);
test(r==KErrNone);
fs1.NotifyChange(ENotifyEntry,reqStat1,path1);
TRequestStatus reqStat2(KRequestPending);
RFs fs2;
r=fs2.Connect();
test(r==KErrNone);
r=fs2.SetSessionPath(gSessionPath);
test(r==KErrNone);
fs2.NotifyChange(ENotifyEntry,reqStat2,path2);
TRequestStatus reqStat3(KRequestPending);
RFs fs3;
r=fs3.Connect();
test(r==KErrNone);
r=fs3.SetSessionPath(gSessionPath);
test(r==KErrNone);
fs3.NotifyChange(ENotifyEntry,reqStat3,path3);
TRequestStatus reqStat4(KRequestPending);
RFs fs4;
r=fs4.Connect();
test(r==KErrNone);
r=fs4.SetSessionPath(gSessionPath);
test(r==KErrNone);
fs4.NotifyChange(ENotifyEntry,reqStat4,path4);
TRequestStatus reqStat5(KRequestPending);
RFs fs5;
r=fs5.Connect();
test(r==KErrNone);
r=fs5.SetSessionPath(gSessionPath);
test(r==KErrNone);
fs5.NotifyChange(ENotifyEntry,reqStat5,path5);
TRequestStatus reqStat6(KRequestPending);
RFs fs6;
r=fs6.Connect();
test(r==KErrNone);
r=fs6.SetSessionPath(gSessionPath);
test(r==KErrNone);
fs6.NotifyChange(ENotifyEntry,reqStat6,path6);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
test(reqStat6==KRequestPending);
// Make a change a the top level and check that only the session monitoring
// that level is notified
test.Next(_L("Test only client monitoring top level is notified"));
r=file.Replace(TheFs,_L("\\F32-TST\\NewFile.txt"),EFileStream);
test(r==KErrNone);
file.Close();
User::WaitForRequest(reqStat1);
test(reqStat1==KErrNone);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
User::WaitForRequest(reqStat6);
test(reqStat6==KErrNone);
r=TheFs.Delete(_L("\\F32-TST\\NewFile.txt"));
test(r==KErrNone);
// Renew the notify request at the top level and make a change one step lower
fs1.NotifyChange(ENotifyEntry,reqStat1,path1);
fs6.NotifyChange(ENotifyEntry,reqStat6,path6);
test(reqStat1==KRequestPending);
test(reqStat6==KRequestPending);
test.Next(_L("Test clients monitoring levels 1 and 2 are notified"));
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileStream);
test(r==KErrNone);
file.Close();
User::WaitForRequest(reqStat1);
User::WaitForRequest(reqStat2);
test(reqStat1==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
User::WaitForRequest(reqStat6);
test(reqStat6==KErrNone);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\NewFile.txt"));
test(r==KErrNone);
// Renew the notify request at the top and second levels and make a change
// one step lower still
fs1.NotifyChange(ENotifyEntry,reqStat1,path1);
fs2.NotifyChange(ENotifyEntry,reqStat2,path2);
fs6.NotifyChange(ENotifyEntry,reqStat6,path6);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat6==KRequestPending);
test.Next(_L("Test clients monitoring levels 1,2 and 3 are notified"));
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\ANIMAL\\NewFile.txt"),EFileStream);
test(r==KErrNone);
file.Close();
User::WaitForRequest(reqStat1);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat1==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
User::WaitForRequest(reqStat6);
test(reqStat6==KErrNone);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\ANIMAL\\NewFile.txt"));
test(r==KErrNone);
// Renew the notify request at the top, second and third levels and make a change
// one step lower still
fs1.NotifyChange(ENotifyEntry,reqStat1,path1);
fs2.NotifyChange(ENotifyEntry,reqStat2,path2);
fs3.NotifyChange(ENotifyEntry,reqStat3,path3);
fs6.NotifyChange(ENotifyEntry,reqStat6,path6);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat6==KRequestPending);
test.Next(_L("Test clients monitoring levels 1 - 4 are notified"));
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\ANIMAL\\cat.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat1);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
User::WaitForRequest(reqStat4);
test(reqStat1==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KErrNone);
test(reqStat5==KRequestPending);
User::WaitForRequest(reqStat6);
test(reqStat6==KErrNone);
// Renew the notify request at the top, second and third levels and on the file deleted above
// which will be successful, but will not complete (for obvious reasons)
// Make a change one step lower still
fs1.NotifyChange(ENotifyEntry,reqStat1,path1);
fs2.NotifyChange(ENotifyEntry,reqStat2,path2);
fs3.NotifyChange(ENotifyEntry,reqStat3,path3);
fs6.NotifyChange(ENotifyEntry,reqStat6,path6);
fs4.NotifyChange(ENotifyEntry,reqStat4,path4);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
test(reqStat6==KRequestPending);
test.Next(_L("Test clients monitoring levels 1 - 3 and 5 are notified"));
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\ANIMAL\\dog.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat1);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
// Don't wait for reqStat4
User::WaitForRequest(reqStat5);
User::WaitForRequest(reqStat6);
test(reqStat1==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending); // File does not exist
test(reqStat5==KErrNone);
test(reqStat6==KErrNone);
fs4.NotifyChangeCancel(reqStat4);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// Renew the notify request at the top, second and third levels and attempt to renew
// the request on the files deleted above (which will fail).
test.Next(_L("Test clients monitoring levels 1 - 3 are notified"));
fs1.NotifyChange(ENotifyEntry,reqStat1,path1);
fs2.NotifyChange(ENotifyEntry,reqStat2,path2);
fs3.NotifyChange(ENotifyEntry,reqStat3,path3);
fs4.NotifyChange(ENotifyEntry,reqStat4,path4);
fs6.NotifyChange(ENotifyEntry,reqStat6,path6);
fs5.NotifyChange(ENotifyEntry,reqStat5,path5);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
test(reqStat6==KRequestPending);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\ANIMAL\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat1);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat1==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
User::WaitForRequest(reqStat6);
test(reqStat6==KErrNone);
// Renew the notify request at the top and second levels on the third level
// which was removed - it'll succeed but won't complete.
test.Next(_L("Test clients monitoring levels 1 and 2 are notified"));
test.Next(_L("Test clients' attempts to monitor levels 3-5 fail"));
fs1.NotifyChange(ENotifyEntry,reqStat1,path1);
fs2.NotifyChange(ENotifyEntry,reqStat2,path2);
fs3.NotifyChange(ENotifyEntry,reqStat3,path3);
fs6.NotifyChange(ENotifyEntry,reqStat6,path6);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
test(reqStat6==KRequestPending);
fs1.NotifyChangeCancel();
fs2.NotifyChangeCancel();
fs1.Close();
fs2.Close();
// Close the other sessions with requests outstanding to test that there's no evilness
fs3.Close();
fs4.Close();
fs5.Close();
fs6.Close();
User::WaitForRequest(reqStat1);
User::WaitForRequest(reqStat2);
// Closing file server sessions doesn't seem to complete notifications, is this a bug?
// User::WaitForRequest(reqStat3);
// User::WaitForRequest(reqStat4);
// User::WaitForRequest(reqStat5);
// User::WaitForRequest(reqStat6);
}
static void Test10()
//
// Test notify cancel
//
{
test.Next(_L("Cancel notification request using simple function"));
TFileName path=_L("\\F32-TST\\NOTIFY\\");
RFs fs1;
TInt r=fs1.Connect();
test(r==KErrNone);
r=fs1.SetSessionPath(gSessionPath);
test(r==KErrNone);
TRequestStatus status1;
TRequestStatus status2;
TRequestStatus status3;
TRequestStatus status4;
TRequestStatus status5;
fs1.NotifyChange(ENotifyAll,status1,path);
fs1.NotifyChange(ENotifyAll,status2,path);
fs1.NotifyChange(ENotifyAll,status3,path);
fs1.NotifyChange(ENotifyAll,status4,path);
fs1.NotifyChange(ENotifyAll,status5,path);
test(status1==KRequestPending);
test(status2==KRequestPending);
test(status3==KRequestPending);
test(status4==KRequestPending);
test(status5==KRequestPending);
test.Next(_L("RFs::NotifyCancel()"));
// Test that one call to RFs::NotifyCancel() cancels all outstanding requests
fs1.NotifyChangeCancel();
User::WaitForRequest(status1);
test(status1==KErrCancel);
User::WaitForRequest(status2);
test(status2==KErrCancel);
User::WaitForRequest(status3);
test(status3==KErrCancel);
User::WaitForRequest(status4);
test(status4==KErrCancel);
User::WaitForRequest(status5);
test(status5==KErrCancel);
// Call the cancel function again to check no further action
fs1.NotifyChangeCancel();
// Test overloaded function to cancel a single request
test.Next(_L("Cancel notification request using function overload"));
fs1.NotifyChange(ENotifyAll,status1,path);
fs1.NotifyChange(ENotifyAll,status2,path);
fs1.NotifyChange(ENotifyAll,status3,path);
fs1.NotifyChange(ENotifyAll,status4,path);
fs1.NotifyChange(ENotifyAll,status5,path);
test(status1==KRequestPending);
test(status2==KRequestPending);
test(status3==KRequestPending);
test(status4==KRequestPending);
test(status5==KRequestPending);
// Cancel the outstanding request with status5
test.Next(_L("RFs::NotifyCancel()"));
fs1.NotifyChangeCancel(status5);
User::WaitForRequest(status5);
test(status1==KRequestPending);
test(status2==KRequestPending);
test(status3==KRequestPending);
test(status4==KRequestPending);
test(status5==KErrCancel);
r=TheFs.MkDir(_L("\\F32-TST\\TROPICANA\\"));
test(r==KErrNone);
test(status1==KRequestPending);
test(status2==KRequestPending);
test(status3==KRequestPending);
test(status4==KRequestPending);
fs1.NotifyChangeCancel(status2);
User::WaitForRequest(status2);
test(status1==KRequestPending);
test(status2==KErrCancel);
test(status3==KRequestPending);
test(status4==KRequestPending);
r=TheFs.RmDir(_L("\\F32-TST\\TROPICANA\\"));
test(r==KErrNone);
test(status1==KRequestPending);
test(status3==KRequestPending);
test(status4==KRequestPending);
fs1.NotifyChangeCancel(status4);
User::WaitForRequest(status4);
test(status1==KRequestPending);
test(status3==KRequestPending);
test(status4==KErrCancel);
fs1.NotifyChangeCancel(status4); // Test no side effects on trying to cancel a request
test(status4==KErrCancel); // that has already been cancelled
fs1.NotifyChangeCancel(status1);
User::WaitForRequest(status1);
test(status1==KErrCancel);
test(status3==KRequestPending);
fs1.NotifyChangeCancel(status1); // Test no side effects on trying to cancel a request
test(status1==KErrCancel); // that has already been cancelled
fs1.NotifyChangeCancel(status3);
User::WaitForRequest(status3);
test(status3==KErrCancel);
fs1.Close();
}
static void Test11()
//
// Test notify client death
//
{
test.Next(_L("Kill client while it is monitoring changes to a directory"));
// Call CreateLocal to create RSemaphore gSleepThread which is local to this process
TInt r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread clientThread;
r=clientThread.Create(_L("ClientThread"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest9);
test(r==KErrNone);
clientThread.Resume();
gSleepThread.Wait(); // Wait for gSleepThread to be signalled
// Client thread is waiting for notification of changes
// to directory \\F32-TST\\NOTIFY
TBool jit = User::JustInTime();
User::SetJustInTime(EFalse);
clientThread.Panic(_L("Test client thread panic"),KErrGeneral); // Panic client
User::SetJustInTime(jit);
clientThread.Close();
// Make a change and check there's no disaster
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\"));
test(r==KErrNone || r==KErrAlreadyExists);
MakeFile(_L("\\F32-TST\\NOTIFY\\NewFile.Txt"));
User::After(1000);
}
static void Test12()
//
// Test reads and writes do not cause notification under ENotifyEntry
// Test reads and writes do cause notification under ENotifyAll
//
{
test.Next(_L("Test reads and writes do not cause notification under ENotifyEntry"));
RFile file;
TInt r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\kangaroo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\koala.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\dingo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
TFileName path=_L("\\F32-TST\\NOTIFY\\");
TRequestStatus reqStat1(KRequestPending);
RFs fs1;
r=fs1.Connect();
test(r==KErrNone);
r=fs1.SetSessionPath(gSessionPath);
test(r==KErrNone);
fs1.NotifyChange(ENotifyEntry,reqStat1,path);
TRequestStatus reqStat2(KRequestPending);
RFs fs2;
r=fs2.Connect();
test(r==KErrNone);
r=fs2.SetSessionPath(gSessionPath);
test(r==KErrNone);
fs2.NotifyChange(ENotifyEntry,reqStat2,path);
TRequestStatus reqStat3(KRequestPending);
RFs fs3;
r=fs3.Connect();
test(r==KErrNone);
r=fs3.SetSessionPath(gSessionPath);
test(r==KErrNone);
fs3.NotifyChange(ENotifyEntry,reqStat3,path);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread thread1;
r=thread1.Create(_L("TestThread1"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest5);
test(r==KErrNone);
thread1.Resume();
gSleepThread.Wait();
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\kangaroo.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat1);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat1==KErrNone); // All three notifications occur because they
test(reqStat2==KErrNone); // are all monitoring the top level directory
test(reqStat3==KErrNone); // Later, we'll test monitoring individual files...
gSleepThread.Close();
thread1.Close();
test.Next(_L("Test reads and writes do cause notification under ENotifyAll"));
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\kangaroo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
fs1.NotifyChange(ENotifyAll,reqStat1,path);
fs2.NotifyChange(ENotifyAll,reqStat2,path);
fs3.NotifyChange(ENotifyAll,reqStat3,path);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread thread2;
r=thread2.Create(_L("TestThread2"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest5);
test(r==KErrNone);
thread2.Resume();
gSleepThread.Wait();
User::WaitForRequest(reqStat1);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat1==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
gSleepThread.Close();
thread2.Close();
test.Next(_L("Monitor reads and writes on specific files with either TNotifyType"));
TFileName path1=path;
TFileName path2=path;
TFileName path3=path;
path1+=_L("kangaroo.txt");
path2+=_L("koala.txt");
path3+=_L("dingo.txt");
fs1.NotifyChange(ENotifyAll,reqStat1,path1);
fs2.NotifyChange(ENotifyEntry,reqStat2,path2);
fs3.NotifyChange(ENotifyAll,reqStat3,path3);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread thread3;
r=thread3.Create(_L("TestThread3"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest5);
test(r==KErrNone);
thread3.Resume();
gSleepThread.Wait();
User::WaitForRequest(reqStat1);
test(reqStat1==KErrNone);
test(reqStat2==KRequestPending); // Monitoring with ENotifyEntry
User::WaitForRequest(reqStat3);
test(reqStat3==KErrNone);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\koala.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat2);
test(reqStat2==KErrNone);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\kangaroo.txt"));
test(r==KErrNone);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\dingo.txt"));
test(r==KErrNone);
gSleepThread.Close();
thread3.Close();
fs1.Close();
fs2.Close();
fs3.Close();
}
static void Test13()
//
// Test file notification
//
{
RFs fs; // Session to be notified of any changes
TInt r=fs.Connect();
test(r==KErrNone);
r=fs.SetSessionPath(gSessionPath);
test(r==KErrNone);
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\"));
test(r==KErrNone||r==KErrAlreadyExists);
RFile file;
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\WickedWitch.msg"),EFileStream);
test(r==KErrNone||KErrAlreadyExists);
file.Close();
// Test notification on a specific file
test.Next(_L("Monitor changes to a specific file"));
TFileName path=_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\WickedWitch.msg");
TRequestStatus reqStat(KRequestPending);
TRequestStatus thrdStat(KRequestPending);
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
RThread thread;
r=thread.Create(_L("MyThread7"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest8);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
thread.Close();
// Test notification does not occur if a change is made above the file
fs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=thread.Create(_L("MyThread8"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest1);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
User::After(500000);
thread.Close();
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\NEWFILE.TXT"));
test(r==KErrNone);
// Test notification does not occur if a change is made to another file
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Lion.log"),EFileStream);
test(r==KErrNone);
test(reqStat==KRequestPending);
file.Close();
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Lion.log"));
test(r==KErrNone);
test(reqStat==KRequestPending);
// Test notification occurs when a change is made to the file
test.Next(_L("Delete monitored file"));
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\WickedWitch.Msg"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.Close();
}
static void Test14()
{
//
// Test notification request succeeds with all RFile and RFs operations which result in
// notifications
//
RFs fs;
TInt r=fs.Connect(); // Session to be notified of any changes
test(r==KErrNone);
r=fs.SetSessionPath(gSessionPath);
test(r==KErrNone);
// RFile::Write() to a file within the monitored directory
test.Next(_L("RFile::Write()"));
TFileName path=_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.Doc");
TRequestStatus reqStat(KRequestPending);
RFile file;
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.Write(0,_L8("Pay no attention to the man behind the curtain"));
test(r==KErrNone);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Read() a file within the monitored directory - no notification for reads
path=_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\");
TBuf8<100> temp;
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
r=file.Read(0,temp,100);
test(reqStat==KRequestPending);
// RFile::SetAtt() of a file within the monitored directory
test.Next(_L("RFile::SetAtt()"));
r=file.SetAtt(KEntryAttSystem,KEntryAttNormal);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
// RFile::SetSize() of a file within the monitored directory
test.Next(_L("RFile::SetSize()"));
r=file.SetSize(256);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFile::Temp() to create a temp file within the monitored directory
test.Next(_L("RFile::Temp()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
TFileName fileName;
r=file.Temp(TheFs,path,fileName,EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFile::SetModified() to change modification time of a file within monitored dir
test.Next(_L("RFile::SetModified()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
TTime now;
now.HomeTime();
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
file.SetModified(now);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::SetEntry() to change a directory entry within the monitored directory
test.Next(_L("RFs::SetEntry()"));
TEntry entry;
fs.NotifyChange(ENotifyAll,reqStat,path);
r=TheFs.Entry(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),entry);
test(reqStat==KRequestPending);
now.HomeTime();
r=TheFs.SetEntry(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),now,KEntryAttHidden,KEntryAttNormal);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Set() to change file's modification time and attributes
test.Next(_L("RFile::Set()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
now.HomeTime();
r=file.Set(now,KEntryAttNormal,KEntryAttHidden);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::SetDriveName()
test.Next(_L("RFs::SetDriveName()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
User::After(KNotifyChangeAfter);
r=TheFs.SetDriveName(KDefaultDrive,_L("DRIVETEST"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.NotifyChange(ENotifyEntry,reqStat,path);
User::After(KNotifyChangeAfter);
r=TheFs.SetDriveName(KDefaultDrive,_L("TEST"));
test(r==KErrNone);
test(reqStat==KRequestPending);
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
fs.NotifyChange(ENotifyDisk,reqStat,path);
User::After(KNotifyChangeAfter);
r=TheFs.SetDriveName(KDefaultDrive,_L("DRIVE"));
test(r==KErrNone);
test(reqStat==KRequestPending);
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// RFs::MkDir()
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
test.Next(_L("RFs::MkDir()"));
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::RmDir()
test.Next(_L("RFs::RmDir()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Create()
test.Next(_L("RFile::Create()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.Create(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFs::Delete()
test.Next(_L("RFs::Delete()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Replace()
test.Next(_L("RFile::Replace()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFs::Delete()
test.Next(_L("RFs::Delete()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::SetVolumeLabel() - should only be notification when monitoring relevant TNotifyTypes
test.Next(_L("RFs::SetVolumeLabel"));
fs.NotifyChange(ENotifyAll,reqStat,path);
TInt driveNum=CurrentDrive();
TVolumeInfo volInfo;
TFileName currentVolName;
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(reqStat==KRequestPending);
currentVolName=volInfo.iName;
r=TheFs.SetVolumeLabel(_L("VOL"),driveNum);
if (r==KErrNone)
{
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==_L("VOL"));
// Test notification occurs under ENotifyDisk
fs.NotifyChange(ENotifyDisk,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.SetVolumeLabel(_L("ABCDEFGHIJK"),driveNum);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==_L("ABCDEFGHIJK"));
// Test notification does not occur under ENotifyAttributes
fs.NotifyChange(ENotifyAttributes,reqStat,path);
r=TheFs.SetVolumeLabel(_L("TROPICANA"),driveNum);
test(r==KErrNone);
test(reqStat==KRequestPending);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==_L("TROPICANA"));
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Test notification occurs under ENotifyEntry
fs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.SetVolumeLabel(currentVolName,driveNum);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==currentVolName);
}
else // RFs::SetVolumeLabel() doesn't work on subst drives
{
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat);
test.Printf(_L("Cannot set volume label on a substed drive\n"));
}
// RFs::Rename()
test.Next(_L("RFs::Rename()"));
fs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Rename(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Toto.doc"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Rename(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Toto.doc"),_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"));
test(r==KErrNone);
#if defined(__WINS__)
if(gSessionPath[0]=='Y'||gSessionPath[0]=='X')
#endif
{
test.Next(_L("RFs::Rename() with max path length"));
TFileName longName=_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\");
while(longName.Length()<(KMaxFileName-2))
longName+=_L("a");
r=TheFs.Rename(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),longName);
test(r==KErrNone);
fs.NotifyChange(ENotifyEntry,reqStat,longName);
test(reqStat==KRequestPending);
r=TheFs.Rename(longName,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
}
fs.Close();
}
static void Test15()
{
//
// Repeat Test15 operations in a subtree of that monitored, and ensure notification
// occurs for a variety of RFile and RFs operations
//
RFs fs; // Session to be notified when a change occurs
TInt r=fs.Connect();
test(r==KErrNone);
r=fs.SetSessionPath(gSessionPath);
test(r==KErrNone);
// RFile::Write() to a file in the subtree
test.Next(_L("RFile::Write()"));
TFileName path=_L("\\F32-TST\\NOTIFY\\");
TRequestStatus reqStat(KRequestPending);
fs.NotifyChange(ENotifyAll,reqStat,path);
RFile file;
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
r=file.Write(0,_L8("Pay no attention to the man behind the curtain"));
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Read() a file within the monitored directory - no notification for reads
fs.NotifyChange(ENotifyAll,reqStat,path);
TBuf8<100> temp;
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
r=file.Read(0,temp,100);
test(reqStat==KRequestPending);
// RFile::SetAtt() of a file within the monitored directory
test.Next(_L("RFile::SetAtt()"));
r=file.SetAtt(KEntryAttNormal,KEntryAttHidden);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::SetSize() of a file within the monitored directory
test.Next(_L("RFile::SetSize()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.SetSize(256);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFile::Temp() to create a temp file in the subtree
test.Next(_L("RFile::Temp()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
TFileName fileName;
r=file.Temp(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\"),fileName,EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFile::SetModified() to change modification time of a file within monitored dir
test.Next(_L("RFile::SetModified()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
TTime now;
now.HomeTime();
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
file.SetModified(now);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::Entry() to change a directory entry within the monitored directory
test.Next(_L("RFs::Entry()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
TEntry entry;
r=TheFs.Entry(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),entry);
test(reqStat==KRequestPending);
now.HomeTime();
r=TheFs.SetEntry(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),now,KEntryAttHidden,KEntryAttNormal);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Set() to change file's modification time and attributes
test.Next(_L("RFile::Set()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
now.HomeTime();
r=file.Set(now,KEntryAttNormal,KEntryAttHidden);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::SetDriveName()
test.Next(_L("RFs::SetDriveName()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
User::After(KNotifyChangeAfter);
r=TheFs.SetDriveName(KDefaultDrive,_L("DRIVETEST"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.NotifyChange(ENotifyEntry,reqStat,path);
r=TheFs.SetDriveName(KDefaultDrive,_L("TEST"));
test(r==KErrNone);
test(reqStat==KRequestPending);
User::After(KNotifyChangeAfter);
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
fs.NotifyChange(ENotifyDisk,reqStat,path);
User::After(KNotifyChangeAfter);
r=TheFs.SetDriveName(KDefaultDrive,_L("DRIVE"));
test(r==KErrNone);
test(reqStat==KRequestPending);
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// RFs::MkDir()
test.Next(_L("RFs::MkDir()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::RmDir()
test.Next(_L("RFs::RmDir()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Create()
test.Next(_L("RFile::Create()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.Create(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFs::Delete()
test.Next(_L("RFs::Delete()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Replace()
test.Next(_L("RFile::Replace()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFs::Delete()
test.Next(_L("RFs::Delete()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::SetVolumeLabel() - should be notification under relevant TNotifyType monitoring
// The operation is non-path specific so all outstanding interested requests are notified
test.Next(_L("RFs::SetVolumeLabel()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
TInt driveNum=CurrentDrive();
TVolumeInfo volInfo;
TFileName currentVolName;
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(reqStat==KRequestPending);
currentVolName=volInfo.iName;
r=TheFs.SetVolumeLabel(_L("VOL"),driveNum);
if (r==KErrNone)
{
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==_L("VOL"));
// Test notification occurs under ENotifyDisk
fs.NotifyChange(ENotifyDisk,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.SetVolumeLabel(_L("ABCDEFGHIJK"),driveNum);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==_L("ABCDEFGHIJK"));
// Test notification does not occur under ENotifyAttributes
fs.NotifyChange(ENotifyAttributes,reqStat,path);
r=TheFs.SetVolumeLabel(_L("TROPICANA"),driveNum);
test(r==KErrNone);
test(reqStat==KRequestPending);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==_L("TROPICANA"));
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Test notification occurs under ENotifyEntry
fs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.SetVolumeLabel(currentVolName,driveNum);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==currentVolName);
}
else // RFs::SetVolumeLabel() doesn't work on subst drives
{
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat);
test.Printf(_L("Cannot set volume label on a substed drive\n"));
}
// Test that notification is made when change is made to monitored directory
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.Close();
}
static void Test16()
{
//
// Repeat Test15 operations in a subtree of that monitored, and ensure notification
// does occur for a variety of file operations when subtree watching is on
//
RFs fs;
TInt r=fs.Connect(); // Session to be notified when a change occurs
test(r==KErrNone);
r=fs.SetSessionPath(gSessionPath);
test(r==KErrNone);
// RFile::Write() to a file in the subtree
TFileName path=_L("\\F32-TST\\NOTIFY\\");
TRequestStatus reqStat(KRequestPending);
fs.NotifyChange(ENotifyAll,reqStat,path);
RFile file;
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
r=file.Write(0,_L8("Pay no attention to the man behind the curtain"));
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Read() a file within the monitored directory - no notification for reads
fs.NotifyChange(ENotifyAll,reqStat,path);
TBuf8<100> temp;
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
r=file.Read(0,temp,100);
test(reqStat==KRequestPending);
// RFile::SetAtt() of a file within the monitored directory
r=file.SetAtt(KEntryAttNormal,KEntryAttHidden);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::SetSize() of a file within the monitored directory
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.SetSize(256);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFile::SetModified() to change modification time of a file within monitored dir
fs.NotifyChange(ENotifyAll,reqStat,path);
TTime now;
now.HomeTime();
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
file.SetModified(now);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::Entry() to change a directory entry within the monitored directory
fs.NotifyChange(ENotifyAll,reqStat,path);
TEntry entry;
r=TheFs.Entry(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),entry);
test(reqStat==KRequestPending);
now.HomeTime();
r=TheFs.SetEntry(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),now,KEntryAttHidden,KEntryAttNormal);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Set() to change file's modification time and attributes
fs.NotifyChange(ENotifyAll,reqStat,path);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
now.HomeTime();
r=file.Set(now,KEntryAttNormal,KEntryAttHidden);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::SetDriveName() - should be no notification ever with extended notification
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
User::After(KNotifyChangeAfter);
r=TheFs.SetDriveName(KDefaultDrive,_L("DRIVETEST"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.NotifyChange(ENotifyEntry,reqStat,path);
User::After(KNotifyChangeAfter);
r=TheFs.SetDriveName(KDefaultDrive,_L("TEST"));
test(r==KErrNone);
test(reqStat==KRequestPending);
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
fs.NotifyChange(ENotifyDisk,reqStat,path);
User::After(KNotifyChangeAfter);
r=TheFs.SetDriveName(KDefaultDrive,_L("DRIVE"));
test(r==KErrNone);
test(reqStat==KRequestPending);
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// RFs::MkDir()
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::RmDir()
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Create()
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.Create(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFs::Delete()
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFile::Replace()
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
file.Close();
// RFs::Delete()
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Good_Witch.bat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// RFs::SetVolumeLabel()
// Not path specific, so all outstanding requests of correct TNotifyType are notified
fs.NotifyChange(ENotifyAll,reqStat,path);
TInt driveNum=CurrentDrive();
TVolumeInfo volInfo;
TFileName currentVolName;
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(reqStat==KRequestPending);
currentVolName=volInfo.iName;
r=TheFs.SetVolumeLabel(_L("VOL"),driveNum);
if (r==KErrNone)
{
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==_L("VOL"));
// Test notification occurs under ENotifyDisk
fs.NotifyChange(ENotifyDisk,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.SetVolumeLabel(_L("ABCDEFGHIJK"),driveNum);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==_L("ABCDEFGHIJK"));
// Test notification does not occur under ENotifyAttributes
fs.NotifyChange(ENotifyAttributes,reqStat,path);
r=TheFs.SetVolumeLabel(_L("TROPICANA"),driveNum);
test(r==KErrNone);
test(reqStat==KRequestPending);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==_L("TROPICANA"));
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
// Test notification occurs under ENotifyEntry
fs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.SetVolumeLabel(currentVolName,driveNum);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==currentVolName);
}
else // RFs::SetVolumeLabel() doesn't work on subst drives
{
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat);
test.Printf(_L("Cannot set volume label on a substed drive\n"));
}
// RFs::Rename()
fs.NotifyChange(ENotifyEntry,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.Rename(_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Dorothy.doc"),_L("\\F32-TST\\NOTIFY\\MUNCHKINS\\Toto.doc"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
// Test that notification is made when change is made to monitored directory
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs.Close();
}
static void Test17()
//
// Test multiple requests from a single session
//
{
test.Next(_L("Test reads and writes do not cause notification under ENotifyEntry"));
RFile file;
TInt r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\kangaroo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\koala.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\dingo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
RFs fs;
r=fs.Connect();
test(r==KErrNone);
r=fs.SetSessionPath(gSessionPath);
test(r==KErrNone);
TRequestStatus reqStat1(KRequestPending);
TFileName path1=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyEntry,reqStat1,path1);
TRequestStatus status1(KRequestPending);
TRequestStatus status2(KRequestPending);
TRequestStatus status3(KRequestPending);
TRequestStatus status4(KRequestPending);
TRequestStatus status5(KRequestPending);
TRequestStatus status6(KRequestPending);
TRequestStatus statusExtended1(KRequestPending);
TRequestStatus statusExtended2(KRequestPending);
TRequestStatus statusExtended3(KRequestPending);
TRequestStatus statusExtended4(KRequestPending);
TRequestStatus statusExtended5(KRequestPending);
TRequestStatus statusExtended6(KRequestPending);
// Request multiple notifications using standard change notification request
fs.NotifyChange(ENotifyEntry,status1);
fs.NotifyChange(ENotifyEntry,status2);
fs.NotifyChange(ENotifyEntry,status3);
fs.NotifyChange(ENotifyEntry,status4);
fs.NotifyChange(ENotifyEntry,status5);
fs.NotifyChange(ENotifyEntry,status6);
// Request multiple notifications using extended change notification request
fs.NotifyChange(ENotifyEntry,statusExtended1,path1);
fs.NotifyChange(ENotifyEntry,statusExtended2,path1);
fs.NotifyChange(ENotifyEntry,statusExtended3,path1);
fs.NotifyChange(ENotifyEntry,statusExtended4,path1);
fs.NotifyChange(ENotifyEntry,statusExtended5,path1);
fs.NotifyChange(ENotifyEntry,statusExtended6,path1);
TRequestStatus reqStat2(KRequestPending);
TFileName path2=_L("\\F32-TST\\NOTIFY\\kangaroo.txt");
fs.NotifyChange(ENotifyEntry,reqStat2,path2);
TRequestStatus reqStat3(KRequestPending);
TFileName path3=_L("\\F32-TST\\NOTIFY\\koala.txt");
fs.NotifyChange(ENotifyEntry,reqStat3,path3);
TRequestStatus reqStat4(KRequestPending);
TFileName path4=_L("\\F32-TST\\NOTIFY\\dingo.txt");
fs.NotifyChange(ENotifyEntry,reqStat4,path4);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread thread1;
r=thread1.Create(_L("TestThread1"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest5);
test(r==KErrNone);
thread1.Resume();
gSleepThread.Wait();
test(status1==KRequestPending);
test(status2==KRequestPending);
test(status3==KRequestPending);
test(status4==KRequestPending);
test(status5==KRequestPending);
test(status6==KRequestPending);
test(statusExtended1==KRequestPending);
test(statusExtended2==KRequestPending);
test(statusExtended3==KRequestPending);
test(statusExtended4==KRequestPending);
test(statusExtended5==KRequestPending);
test(statusExtended6==KRequestPending);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\kangaroo.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat1);
test(reqStat1==KErrNone);
User::WaitForRequest(status1);
test(status1==KErrNone);
User::WaitForRequest(status2);
test(status2==KErrNone);
User::WaitForRequest(status3);
test(status3==KErrNone);
User::WaitForRequest(status4);
test(status4==KErrNone);
User::WaitForRequest(status5);
test(status5==KErrNone);
User::WaitForRequest(status6);
test(status6==KErrNone);
User::WaitForRequest(statusExtended1);
test(statusExtended1==KErrNone);
User::WaitForRequest(statusExtended2);
test(statusExtended2==KErrNone);
User::WaitForRequest(statusExtended3);
test(statusExtended3==KErrNone);
User::WaitForRequest(statusExtended4);
test(statusExtended4==KErrNone);
User::WaitForRequest(statusExtended5);
test(statusExtended5==KErrNone);
User::WaitForRequest(statusExtended6);
test(statusExtended6==KErrNone);
User::WaitForRequest(reqStat2);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
fs.NotifyChangeCancel(); // Cancels both remaining notification requests
User::WaitForRequest(reqStat3);
User::WaitForRequest(reqStat4);
gSleepThread.Close();
thread1.Close();
test.Next(_L("Test reads and writes do cause notification under ENotifyAll"));
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\kangaroo.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
file.Close();
fs.NotifyChange(ENotifyAll,reqStat1,path1);
fs.NotifyChange(ENotifyEntry,reqStat2,path2);
fs.NotifyChange(ENotifyAll,reqStat3,path3);
fs.NotifyChange(ENotifyEntry,reqStat4,path4);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread thread2;
r=thread2.Create(_L("TestThread2"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest5);
test(r==KErrNone);
thread2.Resume();
gSleepThread.Wait();
User::WaitForRequest(reqStat1);
test(reqStat1==KErrNone);
test(reqStat2==KRequestPending);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
gSleepThread.Close();
thread2.Close();
fs.NotifyChange(ENotifyAll,reqStat1,path1);
fs.NotifyChange(ENotifyAll,reqStat3,path3);
test(reqStat1==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=gSleepThread.CreateLocal(0);
test(r==KErrNone);
RThread thread3;
r=thread3.Create(_L("TestThread3"),ThreadEntryPoint,0x4000,KHeapSize,KHeapSize,(TAny*)ETest5);
test(r==KErrNone);
thread3.Resume();
gSleepThread.Wait();
User::WaitForRequest(reqStat1);
test(reqStat1==KErrNone);
test(reqStat2==KRequestPending); // Monitoring with ENotifyEntry
User::WaitForRequest(reqStat3);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending); // Monitoring with ENotifyEntry
RFs fs2;
r=fs2.Connect();
test(r==KErrNone);
r=fs2.SetSessionPath(gSessionPath);
test(r==KErrNone);
TRequestStatus reqStat(KRequestPending);
fs2.NotifyChange(ENotifyEntry,reqStat);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\kangaroo.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat2);
test(reqStat2==KErrNone);
test(reqStat4==KRequestPending);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
fs2.NotifyChange(ENotifyAll,reqStat);
test(reqStat==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\koala.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
test(reqStat4==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\dingo.txt"));
test(r==KErrNone);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrNone);
gSleepThread.Close();
thread3.Close();
fs.Close();
}
static void Test18()
{
//
// Test notification request succeeds or fails as appropriate to the notification type
// with all file operations which result in notifications
// enum TNotifyType {ENotifyEntry=0x00,ENotifyAll=0x01,ENotifyFile=0x04,ENotifyDir=0x08,
// ENotifyAttributes=0x10,ENotifyWrite=0x20,ENotifyDisk=0x40};
//
RFs fs;
TInt r=fs.Connect(); // Session to be notified of any changes
test(r==KErrNone);
r=fs.SetSessionPath(gSessionPath);
test(r==KErrNone);
// RFile::Write() to a file within the monitored directory
test.Next(_L("RFile::Write()"));
TFileName path=_L("\\F32-TST\\NOTIFY\\NewFile.txt");
TRequestStatus reqStat(KRequestPending);
TRequestStatus reqStat2(KRequestPending);
TRequestStatus reqStat3(KRequestPending);
TRequestStatus reqStat4(KRequestPending);
TRequestStatus reqStat5(KRequestPending);
TRequestStatus reqStat6(KRequestPending);
TRequestStatus reqStat7(KRequestPending);
RFile file;
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyFile,reqStat2,path);
fs.NotifyChange(ENotifyWrite,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
fs.NotifyChange(ENotifyEntry,reqStat5,path);
fs.NotifyChange(ENotifyAttributes,reqStat6,path);
fs.NotifyChange(ENotifyDisk,reqStat7,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrArgument); // Cannot monitor a file with ENotifyDir
test(reqStat5==KRequestPending);
test(reqStat6==KRequestPending);
fs.NotifyChange(ENotifyEntry,reqStat4,path);
test(reqStat4==KRequestPending);
r=file.Write(0,_L8("Pay no attention to the man behind the curtain"));
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
test(reqStat2==KRequestPending); // Monitoring with ENotifyFile
User::WaitForRequest(reqStat3);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending); // Monitoring with ENotifyEntry
test(reqStat5==KRequestPending);
test(reqStat6==KRequestPending);
test(reqStat7==KRequestPending);
fs.NotifyChangeCancel(); // Cancels all outstanding notification requests
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
User::WaitForRequest(reqStat5);
test(reqStat5==KErrCancel);
User::WaitForRequest(reqStat6);
test(reqStat6==KErrCancel);
User::WaitForRequest(reqStat7);
test(reqStat7==KErrCancel);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
// RFile::SetAtt() of a file within the monitored directory
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyFile,reqStat2,path);
fs.NotifyChange(ENotifyEntry,reqStat3,path);
fs.NotifyChange(ENotifyAttributes,reqStat4,path);
fs.NotifyChange(ENotifyDir,reqStat5,path);
fs.NotifyChange(ENotifyWrite,reqStat6,path);
fs.NotifyChange(ENotifyDisk,reqStat7,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
User::WaitForRequest(reqStat5);
test(reqStat5==KErrArgument);
test(reqStat6==KRequestPending);
test(reqStat7==KRequestPending);
test.Next(_L("RFile::SetAtt()"));
r=file.SetAtt(KEntryAttSystem,KEntryAttNormal);
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat4);
test(reqStat==KErrNone);
test(reqStat2==KRequestPending); // Monitoring with ENotifyFile
test(reqStat3==KRequestPending); // Monitoring with ENotifyEntry
test(reqStat4==KErrNone); // Monitoring a file - can't use ENotifyDir
test(reqStat6==KRequestPending);
test(reqStat7==KRequestPending);
fs.NotifyChange(ENotifyWrite,reqStat,path);
test(reqStat==KRequestPending);
fs.NotifyChange(ENotifyDir,reqStat4,path);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrArgument);
r=file.SetAtt(KEntryAttNormal,KEntryAttSystem);
test(r==KErrNone);
test(reqStat==KRequestPending); // Monitoring with ENotifyWrite
fs.NotifyChangeCancel(); // Cancel outstanding notification request
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
User::WaitForRequest(reqStat6);
test(reqStat6==KErrCancel);
User::WaitForRequest(reqStat7);
test(reqStat7==KErrCancel);
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyFile,reqStat2,path);
fs.NotifyChange(ENotifyEntry,reqStat3,path);
fs.NotifyChange(ENotifyAttributes,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
// RFile::SetSize() of a file within the monitored directory
test.Next(_L("RFile::SetSize()"));
r=file.SetSize(256);
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat4);
test(reqStat==KErrNone);
test(reqStat2==KRequestPending); // Monitoring with ENotifyFile
test(reqStat3==KRequestPending); // Monitoring with ENotifyEntry
test(reqStat4==KErrNone);
fs.NotifyChange(ENotifyWrite,reqStat,path);
test(reqStat==KRequestPending);
fs.NotifyChange(ENotifyDir,reqStat4,path);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrArgument);
r=file.SetSize(200);
test(r==KErrNone);
User::After(1000000);
test(reqStat==KRequestPending); // Monitoring with ENotifyWrite
file.Close();
fs.NotifyChangeCancel(); // Cancels all outstanding notification requests
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
// RFile::Temp() to create a temp file within the monitored directory
test.Next(_L("RFile::Temp()"));
path=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyDir,reqStat2,path);
fs.NotifyChange(ENotifyEntry,reqStat3,path);
fs.NotifyChange(ENotifyAttributes,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
TFileName fileName;
r=file.Temp(TheFs,path,fileName,EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending); // Monitoring ENotifyEntry
test(reqStat4==KRequestPending); // Monitoring ENotifyAttributes
file.Close();
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
fs.NotifyChange(ENotifyFile,reqStat,path);
fs.NotifyChange(ENotifyDisk,reqStat2,path);
fs.NotifyChange(ENotifyWrite,reqStat3,path);
r=file.Temp(TheFs,path,fileName,EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending); // Monitoring ENotifyFile
test(reqStat2==KRequestPending); // Monitoring ENotifyDisk
test(reqStat3==KRequestPending); // Monitoring ENotifyWrite
file.Close();
fs.NotifyChangeCancel(); // Cancels all outstanding notification requests
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
// RFile::SetModified() to change modification time of a file within monitored dir
test.Next(_L("RFile::SetModified()"));
path=_L("\\F32-TST\\NOTIFY\\NewFile.txt");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyAttributes,reqStat3,path);
fs.NotifyChange(ENotifyFile,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
TTime now;
now.HomeTime();
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
file.SetModified(now);
file.Close();
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
test(reqStat2==KRequestPending);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// RFs::SetEntry() to change a directory entry within the monitored directory
test.Next(_L("RFs::SetEntry()"));
TEntry entry;
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyAttributes,reqStat3,path);
fs.NotifyChange(ENotifyDisk,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.Entry(_L("\\F32-TST\\NOTIFY\\NewFile.txt"),entry);
test(reqStat==KRequestPending);
now.HomeTime();
r=TheFs.SetEntry(_L("\\F32-TST\\NOTIFY\\NewFile.txt"),now,KEntryAttHidden,KEntryAttNormal);
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KRequestPending);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// RFile::Set() to change file's modification time and attributes
test.Next(_L("RFile::Set()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyAttributes,reqStat3,path);
fs.NotifyChange(ENotifyWrite,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
now.HomeTime();
r=file.Set(now,KEntryAttNormal,KEntryAttHidden);
file.Close();
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KRequestPending);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// RFs::SetDriveName()
test.Next(_L("RFs::SetDriveName()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDisk,reqStat3,path);
fs.NotifyChange(ENotifyAttributes,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
User::After(KNotifyChangeAfter);
r=TheFs.SetDriveName(KDefaultDrive,_L("DRIVETEST"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
test(reqStat==KErrNone);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// RFs::MkDir()
test.Next(_L("RFs::MkDir()"));
path=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDir,reqStat3,path);
fs.NotifyChange(ENotifyFile,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.MkDir(_L("\\F32-TST\\NOTIFY\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
// RFs::RmDir()
test.Next(_L("RFs::RmDir()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyDir,reqStat2,path);
fs.NotifyChange(ENotifyWrite,reqStat3,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
r=TheFs.RmDir(_L("\\F32-TST\\NOTIFY\\EMERALD_CITY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// RFile::Create()
test.Next(_L("RFile::Create()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDir,reqStat3,path);
fs.NotifyChange(ENotifyFile,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=file.Create(TheFs,_L("\\F32-TST\\NOTIFY\\Good_Witch.bat"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat4);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending); // Monitoring ENotifyDir
test(reqStat4==KErrNone);
file.Close();
fs.NotifyChangeCancel(reqStat3);
User::WaitForRequest(reqStat3);
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDisk,reqStat3,path);
fs.NotifyChange(ENotifyWrite,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=file.Create(TheFs,_L("\\F32-TST\\NOTIFY\\Bad_Witch.bat"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
file.Close();
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// RFs::Delete()
test.Next(_L("RFs::Delete()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDir,reqStat3,path);
fs.NotifyChange(ENotifyFile,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\Good_Witch.bat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat4);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending); // Monitoring ENotifyDir
test(reqStat4==KErrNone);
fs.NotifyChangeCancel(reqStat3);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyAttributes,reqStat3,path);
fs.NotifyChange(ENotifyAll,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\Bad_Witch.bat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat4);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending);
test(reqStat4==KErrNone);
fs.NotifyChangeCancel(reqStat3);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
// RFile::Replace()
test.Next(_L("RFile::Replace()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=file.Replace(TheFs,_L("\\F32-TST\\NOTIFY\\Good_Witch.bat"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
file.Close();
fs.NotifyChangeCancel();
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// RFs::Delete()
test.Next(_L("RFs::Delete()"));
path=_L("\\F32-TST\\NOTIFY\\Good_Witch.bat");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrArgument);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\Good_Witch.bat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KErrArgument);
// RFs::SetVolumeLabel()
test.Next(_L("RFs::SetVolumeLabel()"));
path=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
fs.NotifyChange(ENotifyWrite,reqStat5,path);
fs.NotifyChange(ENotifyAttributes,reqStat6,path);
fs.NotifyChange(ENotifyDisk,reqStat7,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
test(reqStat6==KRequestPending);
test(reqStat7==KRequestPending);
TInt driveNum=CurrentDrive();
TVolumeInfo volInfo;
TFileName currentVolName;
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(reqStat==KRequestPending);
currentVolName=volInfo.iName;
r=TheFs.SetVolumeLabel(_L("VOL"),driveNum);
if (r==KErrNone)
{
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat7);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
test(reqStat6==KRequestPending);
test(reqStat7==KErrNone);
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDisk,reqStat7,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat7==KRequestPending);
r=TheFs.SetVolumeLabel(currentVolName,driveNum);
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat7);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
test(reqStat5==KRequestPending);
test(reqStat6==KRequestPending);
test(reqStat7==KErrNone);
r=TheFs.Volume(volInfo,driveNum);
test(r==KErrNone);
test(volInfo.iName==currentVolName);
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
User::WaitForRequest(reqStat5);
test(reqStat5==KErrCancel);
User::WaitForRequest(reqStat6);
test(reqStat6==KErrCancel);
}
else // RFs::SetVolumeLabel() doesn't work on subst drives
{
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
User::WaitForRequest(reqStat4);
User::WaitForRequest(reqStat5);
User::WaitForRequest(reqStat6);
User::WaitForRequest(reqStat7);
test.Printf(_L("Cannot set volume label on a substed drive!\n"));
}
// RFile::Rename()
test.Next(_L("RFile::Rename()"));
path=_L("\\F32-TST\\NOTIFY\\");
file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileShareExclusive|EFileWrite);
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=file.Rename(_L("\\F32-TST\\NOTIFY\\OldFile.abc"));
test(r==KErrNone||r==KErrAlreadyExists);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending); // Monitoring ENotifyDir
file.Close();
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
path=_L("\\F32-TST\\NOTIFY\\OldFile.abc");
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\OldFile.abc"),EFileShareExclusive|EFileWrite);
test(r==KErrNone);
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrArgument);
r=file.Rename(_L("\\F32-TST\\NOTIFY\\NewFile.xyz"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KErrArgument);
file.Close();
// RFs::Rename()
test.Next(_L("RFs::Rename()"));
path=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.Rename(_L("\\F32-TST\\NOTIFY\\NewFile.xyz"),_L("\\F32-TST\\NOTIFY\\NewerFile.cat"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending); // Changed a file not a directory entry
fs.NotifyChangeCancel();
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
path=_L("\\F32-TST\\NOTIFY\\NewerFile.cat");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrArgument);
r=TheFs.Rename(_L("\\F32-TST\\NOTIFY\\NewerFile.cat"),_L("\\F32-TST\\NOTIFY\\Original.dog"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
path=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.Rename(_L("\\F32-TST\\NOTIFY\\"),_L("\\F32-TST\\NOTIFY_TEMP\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
User::WaitForRequest(reqStat4);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone); // Changed a directory entry but notified anyway despite
test(reqStat4==KErrNone); // requesting file notification only because the path we
// were monitoring has changed
path=_L("\\F32-TST\\NOTIFY_TEMP\\Original.dog");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
fs.NotifyChange(ENotifyDir,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrArgument);
r=TheFs.Rename(_L("\\F32-TST\\NOTIFY_TEMP\\"),_L("\\F32-TST\\NOTIFY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone); // Modified a directory above the level at which we
test(reqStat2==KErrNone); // are monitoring for changes - we must be notified
test(reqStat3==KErrNone); // anyway because the path has changed
fs.NotifyChange(ENotifyAll,reqStat,path);
test(reqStat==KRequestPending);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
test(reqStat2==KRequestPending);
fs.NotifyChange(ENotifyFile,reqStat3,path);
test(reqStat3==KRequestPending);
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
fs.NotifyChangeCancel(reqStat2);
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
fs.NotifyChangeCancel(reqStat3);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
path=_L("\\F32-TST\\NOTIFY\\Original.dog");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyFile,reqStat3,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\Original.dog"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
path=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDir,reqStat3,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
r=TheFs.Rename(_L("\\F32-TST\\"),_L("\\F32-TEST\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone); // Modified a directory above the level at which we
test(reqStat2==KErrNone); // are monitoring for changes but we receive notification
test(reqStat3==KErrNone); // because the notification path has been changed
fs.NotifyChange(ENotifyAll,reqStat,path);
// Notification request is submitted, despite the subject's disappearance
test(reqStat==KRequestPending);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
// Notification request is submitted, despite the subject's disappearance
test(reqStat2==KRequestPending);
fs.NotifyChange(ENotifyFile,reqStat3,path);
// Notification request is submitted, despite the subject's disappearance
test(reqStat3==KRequestPending);
fs.NotifyChangeCancel(reqStat);
User::WaitForRequest(reqStat);
test(reqStat==KErrCancel);
fs.NotifyChangeCancel(reqStat2);
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
fs.NotifyChangeCancel(reqStat3);
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
path=_L("\\F32-TEST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDir,reqStat3,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
r=TheFs.Rename(_L("\\F32-TEST\\NOTIFY\\"),_L("\\F32-TEST\\NOTIFY_CHANGED\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone); // Rename the directory we were monitoring
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
// Tidy up the test directory before continuing (while testing notifications of renaming to the monitored directory)
path=_L("\\F32-TST\\NOTIFY_CHANGED\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDir,reqStat3,path);
fs.NotifyChange(ENotifyFile,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.Rename(_L("\\F32-TEST\\"),_L("\\F32-TST\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone); // Renaming to (under) the directory we were monitoring
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
fs.NotifyChangeCancel(reqStat4);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
path=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange(ENotifyEntry,reqStat2,path);
fs.NotifyChange(ENotifyDir,reqStat3,path);
fs.NotifyChange(ENotifyFile,reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.Rename(_L("\\F32-TST\\NOTIFY_CHANGED\\"),_L("\\F32-TST\\NOTIFY\\"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone); // Renaming to the directory we were monitoring
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
fs.NotifyChangeCancel(reqStat4);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// Test combinations of notify types
test.Next(_L("Test combinations of notify types"));
path=_L("\\F32-TST\\NOTIFY\\");
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange((TNotifyType)(KGenericEntryChange|ENotifyAttributes),reqStat2,path);
fs.NotifyChange((TNotifyType)(ENotifyDir|ENotifyFile),reqStat3,path);
fs.NotifyChange((TNotifyType)(ENotifyDisk|ENotifyAttributes),reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=file.Create(TheFs,_L("\\F32-TST\\NOTIFY\\Munchkin.msg"),EFileRead|EFileWrite);
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending); // Monitoring ENotifyAttributes|ENotifyDisk
file.Close();
fs.NotifyChangeCancel(reqStat4);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
// RFile::SetModified()
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange((TNotifyType)(KGenericEntryChange|ENotifyAttributes),reqStat2,path);
fs.NotifyChange((TNotifyType)(ENotifyDir|ENotifyFile),reqStat3,path);
fs.NotifyChange((TNotifyType)(ENotifyDisk|ENotifyAttributes),reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
TTime nowTime;
nowTime.HomeTime();
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\Munchkin.msg"),EFileRead|EFileWrite);
test(r==KErrNone);
test(reqStat==KRequestPending);
file.SetModified(now);
file.Close();
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat4);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KRequestPending);
test(reqStat4==KErrNone);
fs.NotifyChangeCancel();
User::WaitForRequest(reqStat3);
test(reqStat3==KErrCancel);
// RFile::Write()
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange((TNotifyType)(KGenericEntryChange|ENotifyAttributes),reqStat2,path);
fs.NotifyChange((TNotifyType)(ENotifyFile|ENotifyWrite),reqStat3,path);
fs.NotifyChange((TNotifyType)(ENotifyDir|ENotifyWrite),reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=file.Open(TheFs,_L("\\F32-TST\\NOTIFY\\Munchkin.msg"),EFileRead|EFileWrite);
test(r==KErrNone);
r=file.Write(0,_L8("Pay no attention to the man behind the curtain"));
file.Close();
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat3);
User::WaitForRequest(reqStat4);
test(reqStat==KErrNone);
test(reqStat2==KRequestPending);
test(reqStat3==KErrNone);
test(reqStat4==KErrNone);
fs.NotifyChangeCancel(reqStat2); // Cancels all outstanding notification requests
User::WaitForRequest(reqStat2);
test(reqStat2==KErrCancel);
// RFs::Delete()
test.Next(_L("RFs::Delete()"));
fs.NotifyChange(ENotifyAll,reqStat,path);
fs.NotifyChange((TNotifyType)(KGenericEntryChange|ENotifyAttributes),reqStat2,path);
fs.NotifyChange((TNotifyType)(ENotifyFile|ENotifyWrite),reqStat3,path);
fs.NotifyChange((TNotifyType)(ENotifyDir|ENotifyWrite),reqStat4,path);
test(reqStat==KRequestPending);
test(reqStat2==KRequestPending);
test(reqStat3==KRequestPending);
test(reqStat4==KRequestPending);
r=TheFs.Delete(_L("\\F32-TST\\NOTIFY\\Munchkin.msg"));
test(r==KErrNone);
User::WaitForRequest(reqStat);
User::WaitForRequest(reqStat2);
User::WaitForRequest(reqStat3);
test(reqStat==KErrNone);
test(reqStat2==KErrNone);
test(reqStat3==KErrNone);
test(reqStat4==KRequestPending);
fs.NotifyChangeCancel(reqStat4);
User::WaitForRequest(reqStat4);
test(reqStat4==KErrCancel);
fs.Close();
}
#if defined __EPOC32__ && defined __INCLUDE_MANUAL_TESTS__
// Manual media change test
// assumes the media is intially present and then prompts
// the user to remove the media
static void Test99()
{
TBuf<64> b;
b.Format(_L("Test Manual Media change notification (socket:%d)"),gSocketNumber);
test.Next(b);
TRequestStatus reqStat=0;
RFs fs;
TInt r=fs.Connect();
test(r==KErrNone);
TDriveInfo driveInfo;
TInt driveNum = EDriveC + SocketToDrive[gSocketNumber];
// verify TDriveInfo.iType == EMediaHardDisk
r = fs.Drive(driveInfo, driveNum);
test (r == KErrNone);
test.Printf(_L("iType = %d\n"), driveInfo.iType);
test(driveInfo.iType == EMediaHardDisk);
// ask the user to eject the media
TheFs.NotifyChange(ENotifyEntry,reqStat);
test(reqStat==KRequestPending);
test.Printf(_L("Please eject media on drive %C...\n"), 'A' + driveNum);
User::WaitForRequest(reqStat);
test.Printf(_L("Done.\n"));
TInt reqInt=reqStat.Int();
test(reqInt==KErrNone);
User::WaitForRequest(reqStat);
// verify TDriveInfo.iType == EMediaNotPresent
r = fs.Drive(driveInfo, driveNum);
test (r == KErrNone);
test.Printf(_L("iType = %d\n"), driveInfo.iType);
test(driveInfo.iType == EMediaNotPresent);
// ask the user to re-insert the media
TheFs.NotifyChange(ENotifyEntry,reqStat);
test(reqStat==KRequestPending);
test.Printf(_L("Please re-insert media...\n"));
User::WaitForRequest(reqStat);
test.Printf(_L("Done.\n"));
reqInt = reqStat.Int();
test(reqInt==KErrNone);
User::WaitForRequest(reqStat);
// verify TDriveInfo.iType == EMediaHardDisk
r = fs.Drive(driveInfo, driveNum);
test (r == KErrNone);
test.Printf(_L("iType = %d\n"), driveInfo.iType);
test(driveInfo.iType == EMediaHardDisk);
fs.Close();
}
#endif // __INCLUDE_MANUAL_TESTS__
//---------------------------------------------
//! @SYMTestCaseID PBASE-T_NOTIFY-0042
//! @SYMTestType UT
//! @SYMREQ REQ5664
//! @SYMTestCaseDesc Test asynchronous RFile API's
//! @SYMTestActions Test normal asynchronous read, share modes, read cancellation, race conditions
//! (with RFile::SetSize() and RFile::Write()), multiple asynchronous readers.
//! @SYMTestExpectedResults Expected behaviour reached.
//! @SYMTestPriority High
//! @SYMTestStatus Implemented
//---------------------------------------------
static void TestAsyncReader()
//
// Test asynchronous read notifications
//
{
TRequestStatus readStat1(KRequestPending);
TRequestStatus readStat2(KRequestPending);
TRequestStatus thrdStat(KRequestPending);
MakeFile(_L("\\F32-TST\\NOTIFY\\NewFile.Txt"));
test.Next(_L("Test original behaviour of asynchronous read API"));
RFile reader;
TInt r=reader.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileShareAny);
test(r==KErrNone);
TBuf8<596> readBuf;
reader.Read(0, readBuf, 100, readStat1);
User::WaitForRequest(readStat1);
test(readStat1==KErrNone);
test(readBuf.Length()==0);
reader.Close();
test.Next(_L("Test asynchronous read fails in EFileShareExclusive mode"));
r=reader.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileShareExclusive);
test(r==KErrArgument);
test.Next(_L("Test asynchronous read fails in EFileShareReadersOnly mode"));
r=reader.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileShareReadersOnly);
test(r==KErrArgument);
test.Next(_L("Test asynchronous read is cancelled when file is closed"));
r=reader.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileShareAny);
test(r==KErrNone);
reader.Read(0, readBuf, 100, readStat1);
test(readStat1==KRequestPending);
reader.Close();
User::WaitForRequest(readStat1);
test(readStat1==KErrCancel);
test.Next(_L("Test asynchronous read can be cancelled"));
r=reader.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileShareAny);
test(r==KErrNone);
reader.Read(0, readBuf, 100, readStat1);
test(readStat1==KRequestPending);
reader.ReadCancel(readStat1);
User::WaitForRequest(readStat1);
test(readStat1==KErrCancel);
reader.Close();
// DEF105438: File server thread safety issues
// Up the priority of this thread so that we can cancel the request before the drive thread
// runs (to test whether cancelling still works...)
test.Next(_L("Test asynchronous read is cancelled when running at high priority"));
r=reader.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileShareAny);
test(r==KErrNone);
RThread thisThread;
thisThread.SetPriority(EPriorityRealTime);
reader.Read(0, readBuf, 100, readStat1);
test(readStat1==KRequestPending);
reader.ReadCancel(readStat1);
test.Printf(_L("readStat1 %d"), readStat1.Int());
User::WaitForRequest(readStat1);
test(readStat1==KErrCancel);
reader.Close();
thisThread.SetPriority(EPriorityNormal);
test.Next(_L("Test asynchronous read is notified due to RFile::SetSize()"));
r=reader.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileWrite|EFileShareAny);
test(r==KErrNone);
reader.Read(0, readBuf, 100, readStat1);
test(readStat1==KRequestPending);
r = reader.SetSize(100);
test(r==KErrNone);
User::WaitForRequest(readStat1);
test(readStat1==KErrNone);
test(readBuf.Length() == 100);
r=reader.SetSize(0);
test(r==KErrNone);
reader.Close();
test.Next(_L("Test asynchronous read is notified due to RFile::Write()"));
r=reader.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileWrite|EFileShareAny);
test(r==KErrNone);
reader.Read(0, readBuf, 26, readStat1);
test(readStat1==KRequestPending);
RFile writer;
r=writer.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileWrite|EFileShareAny);
writer.Write(_L8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
User::WaitForRequest(readStat1);
test(readStat1==KErrNone);
test(readBuf.Length() == 26);
reader.Close();
writer.Close();
test.Next(_L("Test multiple asynchronous readers notified from separate thread"));
r=reader.Open(TheFs,_L("\\F32-TST\\NOTIFY\\NewFile.txt"),EFileRead|EFileReadAsyncAll|EFileWrite|EFileShareAny);
test(r==KErrNone);
r=reader.SetSize(0);
test(r==KErrNone);
const TInt KReadLen = 26;
test.Printf(_L(">Read%d[%d]\n"), 0, KReadLen);
reader.Read(0, readBuf, KReadLen, readStat1);
TBuf8<596> readBuf2;
test.Printf(_L(">Read%d[%d]\n"), 1, KReadLen);
reader.Read(KReadLen, readBuf2, KReadLen, readStat2);
test(readStat1==KRequestPending);
test(readStat2==KRequestPending);
RThread thread;
r=thread.Create(_L("MyThread"),ThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETest12);
test(r==KErrNone);
thread.Logon(thrdStat);
thread.Resume();
thread.Close();
RTimer timer;
TRequestStatus timerStat(KRequestPending);
timer.CreateLocal();
timer.After(timerStat, 30000000); // 30 seconds timeout (the following async test should take 10 seconds)
test(timerStat==KRequestPending);
#define ODDPASS (pass&0x01)
#define REQSTAT (ODDPASS ? readStat2 : readStat1)
#define PENDSTAT (ODDPASS ? readStat1 : readStat2)
#define COMPLEN (ODDPASS ? KReadLen : (pass+1)*KReadLen)
#define READLEN (ODDPASS ? KReadLen : (pass+3)*KReadLen)
#define READPOS (ODDPASS ? (pass+2)*KReadLen : 0)
#define READBUF (ODDPASS ? readBuf2 : readBuf)
TInt pass = 0;
FOREVER
{
User::WaitForRequest(REQSTAT, timerStat);
test(REQSTAT==KErrNone);
test(timerStat==KRequestPending);
test(READBUF.Length() == COMPLEN);
test(READBUF.Right(KReadLen) == _L8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
test.Printf(_L(">Read%d[%d]\n"), pass&0x01, READLEN);
reader.Read(READPOS, READBUF, READLEN, REQSTAT);
test(REQSTAT==KRequestPending);
if(++pass==10)
break;
}
test.Next(_L("Close reader and test multiple outstanding requests are cancelled"));
timer.Close();
User::WaitForRequest(timerStat);
reader.Close();
User::WaitForRequest(readStat1);
test(readStat1==KErrCancel);
User::WaitForRequest(readStat2);
test(readStat2==KErrCancel);
User::WaitForRequest(thrdStat);
test(thrdStat==KErrNone);
}
//-----------------------------------------------------------------------
/**
Testing that TheFs.NotifyChange() works for the root directory of the drive
*/
void TestRootDirNotifyChange()
{
test.Next(_L("Testing RFs::NotifyChange() on drive's root directory."));
TInt nRes;
TRequestStatus reqStatNotify1(KRequestPending);
_LIT(KTestPath, "\\"); //-- root dir, actually
//-- set up notifier
TheFs.NotifyChange(ENotifyAll, reqStatNotify1, KTestPath);
test(reqStatNotify1.Int() == KRequestPending);
//-- create a file in the root dir
RFile file;
TFileName fileName(KTestPath);
fileName.Append(_L("TestFile.tst"));
nRes=file.Replace(TheFs, fileName, EFileWrite|EFileRead);
test(nRes == KErrNone || nRes ==KErrAlreadyExists);
file.Close();
//-- check that the notifier worked
User::WaitForRequest(reqStatNotify1);
test(reqStatNotify1.Int() == KErrNone);
}
//-----------------------------------------------------------------------
//
// Do all tests
//
GLDEF_C void CallTestsL()
{
CreateTestDirectory(_L("\\F32-TST\\NOTIFY\\"));
// Test RFs::NotifyChange()
CHECK_NO_PENDING_REQUESTS;
Test1();
CHECK_NO_PENDING_REQUESTS;
Test2();
CHECK_NO_PENDING_REQUESTS;
Test3();
CHECK_NO_PENDING_REQUESTS;
Test4();
CHECK_NO_PENDING_REQUESTS;
Test5();
CHECK_NO_PENDING_REQUESTS;
#if defined (__EPOC32__)//we have no removable media on Emulator yet .. ??? we do now
#if defined __INCLUDE_MANUAL_TESTS__
// Media change notification on every socket supported
TInt i;
for (i=0; i<KMaxPBusSockets; i++)
SocketToDrive[i]=-1;
TDriveInfoV1Buf dinfo;
UserHal::DriveInfo(dinfo);
TDriveInfoV1 &di=dinfo();
TInt driveCount=dinfo().iTotalSupportedDrives;
TInt socketCount=dinfo().iTotalSockets;
TInt drv;
test.Printf(_L("Socket count: %d\n"), socketCount);
TUint32 mask=~(0xffffffffu<<socketCount);
for (drv=0; drv<driveCount; drv++)
{
TBool flag=EFalse;
RLocalDrive d;
TInt r=d.Connect(drv,flag);
//Not all the drives are used at present
if (r == KErrNotSupported)
continue;
test(r==KErrNone);
TInt sockNum = 0;
if (d.IsRemovable(sockNum)>0)
{
if (mask & (1<<sockNum))
{
SocketToDrive[sockNum]=drv;
mask &= ~(1<<sockNum);
}
}
d.Close();
}
// Manual media change test
for (gSocketNumber=socketCount-1; gSocketNumber>=0; gSocketNumber--)
{
if (SocketToDrive[gSocketNumber] != -1)
{
test.Printf(_L("Testing socket %u, drive %u...\n"),
gSocketNumber, SocketToDrive[gSocketNumber]);
Test99();
}
}
#endif
Test6();
#endif
CHECK_NO_PENDING_REQUESTS;
Test7();
CHECK_NO_PENDING_REQUESTS;
#if defined (__EPOC32__)//we have no removable media on Emulator yet
// Test RFs::NotifyChange() extended notification
TInt uid;
test(HAL::Get(HAL::EMachineUid,uid)==KErrNone);
if(uid!=HAL::EMachineUid_Cogent && uid!=HAL::EMachineUid_IQ80310 &&
uid != HAL::EMachineUid_Integrator && uid!=HAL::EMachineUid_X86PC)
MediaChangeExtendedNotification();
#endif
CHECK_NO_PENDING_REQUESTS;
TestRequestAhead();
CHECK_NO_PENDING_REQUESTS;
Test8();
CHECK_NO_PENDING_REQUESTS;
Test9();
CHECK_NO_PENDING_REQUESTS;
Test10();
CHECK_NO_PENDING_REQUESTS;
Test11();
CHECK_NO_PENDING_REQUESTS;
Test12();
CHECK_NO_PENDING_REQUESTS;
Test13();
CHECK_NO_PENDING_REQUESTS;
Test14();
CHECK_NO_PENDING_REQUESTS;
Test15();
CHECK_NO_PENDING_REQUESTS;
Test16();
CHECK_NO_PENDING_REQUESTS;
Test17();
CHECK_NO_PENDING_REQUESTS;
Test18();
CHECK_NO_PENDING_REQUESTS;
TestAsyncReader();
CHECK_NO_PENDING_REQUESTS;
DeleteTestDirectory();
CHECK_NO_PENDING_REQUESTS;
TestRootDirNotifyChange();
CHECK_NO_PENDING_REQUESTS;
}