sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // f32test\server\t_hungfs.cpp sl@0: // this test will either run with a secure mmc or will simulate a sl@0: // mmc card. sl@0: // sl@0: // sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include "t_server.h" sl@0: sl@0: GLDEF_D RTest test(_L("T_HUNGFS")); sl@0: GLREF_D RFs TheFs; sl@0: sl@0: LOCAL_D RFile SubFile1; sl@0: LOCAL_D TInt HungReturnCodeC; sl@0: sl@0: LOCAL_D RSemaphore HungSemaphoreC; sl@0: LOCAL_D TInt HungReturnCodeNC; sl@0: LOCAL_D RSemaphore HungSemaphoreNC; sl@0: sl@0: GLREF_C void Format(TInt aDrive); sl@0: sl@0: LOCAL_D const TInt KControlIoLockMount=5; sl@0: LOCAL_D const TInt KControlIoClearLockMount=6; sl@0: LOCAL_D const TInt KControlIoCNotifier=7; sl@0: LOCAL_D const TInt KControlIoClearCNotifier=8; sl@0: sl@0: LOCAL_D const TInt KControlIoCancelNCNotifier=KMaxTInt-1; sl@0: sl@0: LOCAL_D TBool isSecureMmc; sl@0: LOCAL_D TFileName gLockedPath; sl@0: LOCAL_D TFileName gLockedBase; sl@0: LOCAL_D TInt gLockedDrive; sl@0: GLREF_D TFileName gSessionPath; sl@0: LOCAL_D TInt gSessionDrive; sl@0: sl@0: TBuf8<16> KPassword8=_L8("abc"); sl@0: TBuf16<8> KPassword=_L("abc"); sl@0: _LIT(File1,"file1"); sl@0: _LIT(File2,"file2"); sl@0: _LIT(Dir1,"\\dir1\\"); sl@0: _LIT(NotifyDir,"\\not\\"); sl@0: _LIT(NotifyDir2,"\\abc\\"); sl@0: _LIT(HungDirNC,"\\hungnc\\"); sl@0: _LIT(HungDirC,"\\hungc\\"); sl@0: sl@0: LOCAL_D const TInt KHeapSize=0x2000; sl@0: sl@0: struct SNonCriticalInfo sl@0: { sl@0: TBool iSameSession; sl@0: TBool iUseRFile; sl@0: }; sl@0: sl@0: LOCAL_C TInt ThreadFunctionNC(TAny* aInfo) sl@0: // sl@0: // Thread entry point to put up non-critical notifier sl@0: // sl@0: { sl@0: RFs fs; sl@0: TInt r; sl@0: sl@0: TBuf8<8> mmcBuf; sl@0: // pad out password if using lockable mmc sl@0: if(isSecureMmc) sl@0: { sl@0: TUint8 pBuf[]={0x61,0x00,0x62,0x00,0x63,00}; sl@0: mmcBuf.SetLength(6); sl@0: for(TInt i=0;i<6;++i) sl@0: mmcBuf[i]=pBuf[i]; sl@0: } sl@0: sl@0: SNonCriticalInfo* info=NULL; sl@0: if(aInfo!=NULL) sl@0: info=(SNonCriticalInfo*)aInfo; sl@0: sl@0: r=fs.Connect(); sl@0: sl@0: if(isSecureMmc) sl@0: { sl@0: if(info && info->iSameSession) sl@0: r=TheFs.LockDrive(gLockedDrive,NULL,mmcBuf,EFalse); sl@0: else sl@0: { sl@0: r=fs.LockDrive(gLockedDrive,NULL,mmcBuf,EFalse); sl@0: RDebug::Print(_L("l=%d"),r); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if(info && info->iSameSession) sl@0: r=TheFs.ControlIo(gLockedDrive,KControlIoLockMount,KPassword8); sl@0: else sl@0: r=fs.ControlIo(gLockedDrive,KControlIoLockMount,KPassword8); sl@0: } sl@0: // UserSvr::ForceRemountMedia(ERemovableMedia0); sl@0: User::After(300000); sl@0: HungSemaphoreNC.Signal(); sl@0: sl@0: TFileName hungDir=gLockedBase; sl@0: hungDir+=HungDirNC; sl@0: if(info && info->iSameSession) sl@0: r=TheFs.RmDir(hungDir); sl@0: else if(info && info->iSameSession && info->iUseRFile) sl@0: { sl@0: TBuf8<16> buf=_L8("abc"); sl@0: r=SubFile1.Write(buf); sl@0: } sl@0: else sl@0: { sl@0: r=fs.RmDir(hungDir); sl@0: RDebug::Print(_L("rd=%d"),r); sl@0: } sl@0: HungReturnCodeNC=r; sl@0: sl@0: if(isSecureMmc) sl@0: { sl@0: r=fs.UnlockDrive(gLockedDrive,mmcBuf,EFalse); sl@0: r=fs.ClearPassword(gLockedDrive,mmcBuf); sl@0: } sl@0: else sl@0: r=fs.ControlIo(gLockedDrive,KControlIoClearLockMount,KPassword8); sl@0: sl@0: HungSemaphoreNC.Signal(); sl@0: sl@0: fs.Close(); sl@0: sl@0: return(KErrNone); sl@0: } sl@0: sl@0: LOCAL_C TInt ThreadFunctionC(TAny* aDrive) sl@0: // sl@0: // Thread entry point to put up a critical notifier sl@0: // sl@0: { sl@0: RFs fs; sl@0: TInt r=fs.Connect(); sl@0: test(r==KErrNone); sl@0: sl@0: TInt drive; sl@0: #if defined(__WINS__) sl@0: drive=EDriveY; sl@0: #else sl@0: drive=EDriveC; sl@0: #endif sl@0: // can only get critcal notifer up using ControIo sl@0: // assumes fat file system running on one of the drives named below sl@0: r=fs.ControlIo(drive,KControlIoCNotifier); sl@0: sl@0: TBool isRemovable=*(TBool*)aDrive; sl@0: TFileName hungDir=(_L("?:")); sl@0: #if defined(__WINS__) sl@0: if(isRemovable) sl@0: hungDir[0]=(TText)('A'+EDriveX); sl@0: else sl@0: hungDir[0]=(TText)('A'+EDriveY); sl@0: #else sl@0: if(isRemovable) sl@0: hungDir[0]=(TText)('A'+EDriveD); sl@0: else sl@0: hungDir[0]=(TText)('A'+EDriveC); sl@0: #endif sl@0: hungDir+=HungDirC; sl@0: r=fs.RmDir(hungDir); sl@0: r=fs.MkDir(hungDir); sl@0: HungReturnCodeC=r; sl@0: sl@0: r=fs.ControlIo(drive,KControlIoClearCNotifier); sl@0: sl@0: HungSemaphoreC.Signal(); sl@0: r=fs.RmDir(hungDir); sl@0: fs.Close(); sl@0: return(KErrNone); sl@0: } sl@0: sl@0: LOCAL_C void PutNonCriticalNotifier(TAny* aInfo,RThread& aThread) sl@0: // sl@0: // put up a non-critical notifier on a removable media sl@0: // sl@0: { sl@0: TInt r=aThread.Create(_L("ThreadNC"),ThreadFunctionNC,KDefaultStackSize,KMinHeapSize,KMinHeapSize,aInfo); sl@0: test(r==KErrNone); sl@0: aThread.SetPriority(EPriorityMore); sl@0: aThread.Resume(); sl@0: HungSemaphoreNC.Wait(); sl@0: User::After(1000000); sl@0: sl@0: } sl@0: sl@0: LOCAL_C void PutCriticalNotifier(TBool aBool,RThread& aThread) sl@0: // sl@0: // put up a critical notifier on the specified drive sl@0: // sl@0: { sl@0: TInt r=aThread.Create(_L("ThreadC"),ThreadFunctionC,KDefaultStackSize,KMinHeapSize,KMinHeapSize,&aBool); sl@0: test(r==KErrNone); sl@0: aThread.SetPriority(EPriorityMore); sl@0: aThread.Resume(); sl@0: User::After(1000000); sl@0: } sl@0: sl@0: void TestNotifiers() sl@0: // sl@0: // Test non-critical notifier is cancelled when the critical notifier is put up sl@0: // Needs to be carried out on platform with password notifier which handles requests sl@0: // asynchronously and uses CAtaDisk in fat file system on c: drive ie. not internal ram sl@0: // drive sl@0: // sl@0: { sl@0: test.Next(_L("TestNotifiers")); sl@0: if(isSecureMmc) sl@0: return; sl@0: RThread threadNC,threadC; sl@0: PutNonCriticalNotifier(NULL,threadNC); sl@0: PutCriticalNotifier(EFalse,threadC); sl@0: // get rid of critical notifier sl@0: test.Printf(_L("Press cancel on for critcal notifier\n")); sl@0: test.Printf(_L("Press any character\n")); sl@0: test.Getch(); sl@0: TRequestStatus deathStat; sl@0: threadNC.Logon( deathStat ); sl@0: HungSemaphoreC.Wait(); sl@0: // test(HungReturnCodeNC==KErrAbort); sl@0: TRequestStatus deathStat2; sl@0: threadC.Logon(deathStat2); sl@0: HungSemaphoreNC.Wait(); sl@0: //test(HungReturnCodeNC==KErrLocked); sl@0: User::WaitForRequest(deathStat2); sl@0: threadNC.Close(); sl@0: threadC.Close(); sl@0: } sl@0: sl@0: void TestCriticalFunctions() sl@0: // sl@0: // test that only a subset of functions are supported when the critical notifier is up sl@0: // sl@0: { sl@0: test.Next(_L("test functions supported with critical notifier")); sl@0: // used for EFsSubClose sl@0: RFile file; sl@0: TInt r=file.Create(TheFs,File1,EFileShareAny|EFileWrite); sl@0: test(r==KErrNone||KErrAlreadyExists); sl@0: if(r==KErrAlreadyExists) sl@0: { sl@0: r=file.Open(TheFs,File1,EFileShareAny|EFileWrite); sl@0: test(r==KErrNone); sl@0: } sl@0: TBuf8<16> buf=_L8("abcdefghijklmnop"); sl@0: r=file.Write(buf); sl@0: test(r==KErrNone); sl@0: sl@0: r=TheFs.MkDir(NotifyDir); sl@0: test(r==KErrNone); sl@0: sl@0: RThread thread; sl@0: PutCriticalNotifier(ETrue,thread); sl@0: sl@0: // test functions that are supported with critical notifier sl@0: // EFsNotifyChange sl@0: test.Next(_L("test functions that are supported with critical notifier")); sl@0: TRequestStatus status; sl@0: TheFs.NotifyChange(ENotifyAll,status); sl@0: test(status==KRequestPending); sl@0: // EFsNotifyChangeCancel sl@0: TheFs.NotifyChangeCancel(); sl@0: test(status==KErrCancel); sl@0: // EFsNotifyChangeEx sl@0: TheFs.NotifyChange(ENotifyAll,status,gSessionPath); sl@0: test(status==KRequestPending); sl@0: // EFsNotifyChangeCancelEx sl@0: TheFs.NotifyChangeCancel(status); sl@0: test(status==KErrCancel); sl@0: // EFsSubClose sl@0: // difficult to test properly because this does not return an error value sl@0: file.Close(); sl@0: sl@0: // test that notifications are not completed when a critical notifier completes sl@0: test.Next(_L("test notifications not completed")); sl@0: TheFs.NotifyChange(ENotifyDisk,status); sl@0: test(status==KRequestPending); sl@0: TRequestStatus status2; sl@0: TheFs.NotifyChange(ENotifyDir,status2,NotifyDir); sl@0: test(status2==KRequestPending); sl@0: sl@0: // test some functions that are not supported when critcical notifier up sl@0: // EFsFileOpen sl@0: test.Next(_L("test functions that are not supported with critical notifier")); sl@0: r=file.Open(TheFs,File2,EFileShareAny); sl@0: test(r==KErrInUse); sl@0: // EFsFileCreate sl@0: r=file.Create(TheFs,File2,EFileShareAny); sl@0: test(r==KErrInUse); sl@0: // EFsMkDir sl@0: r=TheFs.MkDir(Dir1); sl@0: test(r==KErrInUse); sl@0: // EFsVolume sl@0: TVolumeInfo info; sl@0: r=TheFs.Volume(info,gSessionDrive); sl@0: test(r==KErrInUse); sl@0: sl@0: // get rid of critical notifier sl@0: test.Printf(_L("Press escape on the critical notifier\n")); sl@0: TRequestStatus deathStat; sl@0: thread.Logon(deathStat); sl@0: HungSemaphoreC.Wait(); sl@0: test(HungReturnCodeC==KErrAbort); sl@0: User::WaitForRequest(deathStat); sl@0: thread.Close(); sl@0: sl@0: // test notifiers have not gone off sl@0: test(status==KRequestPending&&status2==KRequestPending); sl@0: sl@0: // test that notification setup on default drive has had the drive changed sl@0: // to * since the critical notifier was up sl@0: TFileName notDir=gLockedBase; sl@0: notDir+=NotifyDir; sl@0: r=TheFs.MkDir(notDir); sl@0: test(r==KErrNone); sl@0: test(status==KRequestPending&&status2==KErrNone); sl@0: TheFs.NotifyChangeCancel(); sl@0: test(status==KErrCancel); sl@0: r=TheFs.Delete(File1); sl@0: test(r==KErrNone); sl@0: r=TheFs.RmDir(notDir); sl@0: test(r==KErrNone); sl@0: r=TheFs.RmDir(NotifyDir); sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: void TestParsingFunctions() sl@0: // sl@0: // Test functions that use Parse* and Validate* functions with sl@0: // non-critical notifier up sl@0: // sl@0: { sl@0: test.Next(_L("TestParsingFunctions")); sl@0: RThread thread; sl@0: PutNonCriticalNotifier(NULL,thread); sl@0: sl@0: // test on same drive as notifier sl@0: test.Next(_L("test parsing functions on same drive")); sl@0: // Using ParseSubst sl@0: TFileName dir=gLockedBase; sl@0: dir+=Dir1; sl@0: TInt r=TheFs.MkDir(dir); sl@0: test(r==KErrInUse); sl@0: TFileName file=gLockedPath; sl@0: file+=File1; sl@0: RFile f; sl@0: r=f.Create(TheFs,file,EFileShareAny); sl@0: test(r==KErrInUse); sl@0: // Using ParsePathPtr0 sl@0: r=TheFs.SetSubst(gLockedPath,EDriveO); sl@0: test(r==KErrInUse); sl@0: // ValidateDrive sl@0: TVolumeInfo info; sl@0: r=TheFs.Volume(info,gLockedDrive); sl@0: test(r==KErrInUse); sl@0: sl@0: TFileName origSessPath; sl@0: r=TheFs.SessionPath(origSessPath); sl@0: test(r==KErrNone); sl@0: sl@0: // test these work ok sl@0: r=TheFs.SetSessionPath(gLockedPath); sl@0: test(r==KErrNone); sl@0: r=TheFs.SetSessionPath(origSessPath); sl@0: test(r==KErrNone); sl@0: sl@0: // test on different drive from notifier - the session path sl@0: test.Next(_L("test parsing functions on a different drive")); sl@0: // Using ParseSubst sl@0: r=TheFs.MkDir(Dir1); sl@0: test(r==KErrNone); sl@0: r=TheFs.RmDir(Dir1); sl@0: test(r==KErrNone); sl@0: r=f.Create(TheFs,File1,EFileShareAny); sl@0: test(r==KErrNone); sl@0: f.Close(); sl@0: r=TheFs.Delete(File1); sl@0: test(r==KErrNone); sl@0: // Using ParsePathPtr0 sl@0: r=TheFs.SetSubst(gSessionPath,EDriveO); sl@0: test(r==KErrNone); sl@0: r=TheFs.SetSubst(_L(""),EDriveO); sl@0: test(r==KErrNone); sl@0: // ValidateDrive sl@0: r=TheFs.Volume(info,gSessionDrive); sl@0: test(r==KErrNone); sl@0: sl@0: // get rid of non-critical notifier sl@0: test.Printf(_L("Enter %S on the notifier\n"),&KPassword); sl@0: sl@0: TRequestStatus deathStat; sl@0: thread.Logon( deathStat ); sl@0: HungSemaphoreNC.Wait(); sl@0: test(HungReturnCodeNC==KErrNotFound); sl@0: User::WaitForRequest( deathStat ); sl@0: thread.Close(); sl@0: sl@0: // test.End(); sl@0: } sl@0: sl@0: void TestTFsFunctions() sl@0: // sl@0: // test functions that do not use the Parse* and Validate* functions sl@0: // sl@0: { sl@0: test.Next(_L("TestTFsFunctions")); sl@0: TFileName sessName,lockedName; sl@0: TInt r=TheFs.FileSystemName(sessName,gSessionDrive); sl@0: test(r==KErrNone); sl@0: r=TheFs.FileSystemName(lockedName,gLockedDrive); sl@0: test(r==KErrNone); sl@0: sl@0: RThread thread; sl@0: PutNonCriticalNotifier(NULL,thread); sl@0: sl@0: // test functions on hung drive - should return KErrInUse sl@0: test.Next(_L("test TFs functions on hung drive")); sl@0: // TFsDismountFileSystem sl@0: r=TheFs.DismountFileSystem(lockedName,gLockedDrive); sl@0: test(r==KErrInUse); sl@0: // TFsMountFileSystem sl@0: r=TheFs.MountFileSystem(lockedName,gLockedDrive); sl@0: test(r==KErrInUse); sl@0: // TFsFileSystemName sl@0: r=TheFs.FileSystemName(lockedName,gLockedDrive); sl@0: test(r==KErrInUse); sl@0: sl@0: // test functions on drive other than hung drive sl@0: test.Next(_L("test TFs functions on drive that is not hung")); sl@0: // TFsDismountFileSystem sl@0: #if defined(__WINS__) sl@0: // bug in TFsMountFileSystem which needs to be fixed before running on EDriveC on WINS sl@0: if(gSessionDrive!=EDriveC) sl@0: { sl@0: #endif sl@0: r=TheFs.DismountFileSystem(sessName,gSessionDrive); sl@0: test(r==KErrNone); sl@0: // TFsMountFileSystem sl@0: r=TheFs.MountFileSystem(sessName,gSessionDrive); sl@0: test(r==KErrNone); sl@0: #if defined(__WINS__) sl@0: } sl@0: #endif sl@0: // TFsFileSystemName sl@0: TFileName fsName; sl@0: r=TheFs.FileSystemName(fsName,gSessionDrive); sl@0: test(r==KErrNone); sl@0: test(fsName==sessName); sl@0: sl@0: // test functions that fail on all drives sl@0: test.Next(_L("test TFs functions that fail on all drives")); sl@0: // TFsListOpenFiles sl@0: CFileList* list=NULL; sl@0: TOpenFileScan fileScan(TheFs); sl@0: TRAP(r,fileScan.NextL(list)); sl@0: test(r==KErrInUse); sl@0: sl@0: // test functions that should pass on any drive sl@0: test.Next(_L("test TFs functions that pass on all drives")); sl@0: // TFsSetDefaultPath sl@0: // TFsSetSessionPath sl@0: r=TheFs.SetSessionPath(gLockedPath); sl@0: test(r==KErrNone); sl@0: r=TheFs.SetSessionPath(gSessionPath); sl@0: test(r==KErrNone); sl@0: sl@0: // get rid of non-critical notifier sl@0: test.Printf(_L("Enter %S on the notifier\n"),&KPassword); sl@0: TRequestStatus deathStat; sl@0: thread.Logon( deathStat ); sl@0: HungSemaphoreNC.Wait(); sl@0: test(HungReturnCodeNC==KErrNotFound); sl@0: User::WaitForRequest( deathStat ); sl@0: thread.Close(); sl@0: // test.End(); sl@0: } sl@0: sl@0: sl@0: void TestSubsessions() sl@0: // sl@0: // test subsession functions sl@0: // sl@0: { sl@0: test.Next(_L("TestSubsessions")); sl@0: RThread thread; sl@0: PutNonCriticalNotifier(NULL,thread); sl@0: sl@0: // test that subsessions cannot be opened on a hung drive sl@0: test.Next(_L("test subsessions cannot be opened on a hung drive")); sl@0: // EFsFileCreate sl@0: RFile file; sl@0: TFileName fileName=gLockedPath; sl@0: fileName+=File1; sl@0: TInt r=file.Create(TheFs,fileName,EFileShareAny); sl@0: test(r==KErrInUse); sl@0: // EFsFormatOpen sl@0: RFormat format; sl@0: TInt count; sl@0: r=format.Open(TheFs,gLockedPath,EHighDensity,count); sl@0: test(r==KErrInUse); sl@0: // EFsDirOpen sl@0: RDir dir; sl@0: r=dir.Open(TheFs,gLockedPath,KEntryAttMaskSupported); sl@0: test(r==KErrInUse); sl@0: // EFsRawDiskOpen sl@0: RRawDisk raw; sl@0: r=raw.Open(TheFs,gLockedDrive); sl@0: test(r==KErrInUse); sl@0: sl@0: // get rid of non-critical notifier sl@0: test.Printf(_L("Enter %S on the notifier\n"),&KPassword); sl@0: TRequestStatus deathStat; sl@0: thread.Logon( deathStat ); sl@0: HungSemaphoreNC.Wait(); sl@0: test(HungReturnCodeNC==KErrNotFound); sl@0: User::WaitForRequest( deathStat ); sl@0: thread.Close(); sl@0: sl@0: // now open the subsessions sl@0: r=file.Create(TheFs,fileName,EFileShareAny); sl@0: test(r==KErrNone||KErrAlreadyExists); sl@0: if(r==KErrAlreadyExists) sl@0: { sl@0: r=file.Open(TheFs,fileName,EFileShareAny); sl@0: test(r==KErrNone); sl@0: } sl@0: r=dir.Open(TheFs,gLockedPath,KEntryAttMaskSupported); sl@0: test(r==KErrNone); sl@0: sl@0: // put notifier back up sl@0: PutNonCriticalNotifier(NULL,thread); sl@0: sl@0: // test subsession operations fail on a hung drive sl@0: test.Next(_L("test subsession operations fail on a hung drive")); sl@0: // EFsFileRead sl@0: TBuf8<16> readBuf; sl@0: r=file.Read(readBuf); sl@0: test(r==KErrInUse); sl@0: // subsession should be able to be closed ok sl@0: file.Close(); sl@0: // EFsDelete sl@0: r=TheFs.Delete(fileName); sl@0: test(r==KErrInUse); sl@0: // EFsDirRead sl@0: TEntry entry; sl@0: r=dir.Read(entry); sl@0: test(r==KErrInUse); sl@0: // subsession should be able to be closed ok sl@0: dir.Close(); sl@0: sl@0: // not going to test operations on a drive the is not hung sl@0: // since this will be tested on other tests sl@0: sl@0: // get rid of non-critical notifier sl@0: test.Printf(_L("Enter %S on the notifier\n"),&KPassword); sl@0: thread.Logon( deathStat ); sl@0: HungSemaphoreNC.Wait(); sl@0: test(HungReturnCodeNC==KErrNotFound); sl@0: User::WaitForRequest( deathStat ); sl@0: thread.Close(); sl@0: sl@0: r=TheFs.Delete(fileName); sl@0: test(r==KErrNone); sl@0: // test.End(); sl@0: } sl@0: sl@0: void TestSameSession() sl@0: // sl@0: // Test functions that can and cannot be handled from same session when notifier is up sl@0: // sl@0: { sl@0: test.Next(_L("TestSameSession")); sl@0: sl@0: RFile file; sl@0: TInt r=file.Create(TheFs,File1,EFileWrite); sl@0: test(r==KErrNone); sl@0: sl@0: // put notifier up using TheFs session sl@0: SNonCriticalInfo info={ETrue,0}; sl@0: RThread thread; sl@0: PutNonCriticalNotifier(&info,thread); sl@0: sl@0: // test critical functions can be handled sl@0: test.Next(_L("test critical functions can be handled")); sl@0: // EFsNotifyChange sl@0: TRequestStatus status; sl@0: TheFs.NotifyChange(ENotifyAll,status); sl@0: test(status==KRequestPending); sl@0: // EFsNotifyChangeCancel sl@0: TheFs.NotifyChangeCancel(); sl@0: test(status==KErrCancel); sl@0: // EFsNotifyChange again sl@0: TheFs.NotifyChange(ENotifyAll,status); sl@0: test(status==KRequestPending); sl@0: // EFsNotifyChangeCancelEx sl@0: TheFs.NotifyChangeCancel(status); sl@0: test(status==KErrCancel); sl@0: // not going to test EFsSubClose sl@0: sl@0: // test other functions are not handled sl@0: test.Next(_L("test other functions cannot be handled")); sl@0: // EFsNotifyChangeEx sl@0: TheFs.NotifyChange(ENotifyAll,status,gSessionPath); sl@0: test(status==KErrInUse); sl@0: TFileName defPath; sl@0: // EFsCheckDisk sl@0: r=TheFs.CheckDisk(gSessionPath); sl@0: test(r==KErrInUse); sl@0: // EFsFileWrite sl@0: _LIT8(buffer,"abc"); sl@0: TBuf8<8> buf(buffer); sl@0: r=file.Write(buf); sl@0: test(r==KErrInUse); sl@0: sl@0: // this file should be able to be closed sl@0: file.Close(); sl@0: sl@0: // get rid of non-critical notifier sl@0: test.Printf(_L("Enter %S on the notifier\n"),&KPassword); sl@0: sl@0: TRequestStatus deathStat; sl@0: thread.Logon( deathStat ); sl@0: HungSemaphoreNC.Wait(); sl@0: test(HungReturnCodeNC==KErrNotFound); sl@0: User::WaitForRequest( deathStat ); sl@0: thread.Close(); sl@0: sl@0: r=TheFs.Delete(File1); sl@0: test(r==KErrNone); sl@0: // test.End(); sl@0: } sl@0: sl@0: void TestSameSubSession() sl@0: // sl@0: // test hung file server with same subsession sl@0: // sl@0: { sl@0: _LIT(file1Name,"\\SubFile1"); sl@0: _LIT(file2Name,"\\SubFile2"); sl@0: _LIT(file3Name,"\\SubFile3"); sl@0: _LIT(file4Name,"\\SubFile4"); sl@0: TFileName origSession; sl@0: TInt r=TheFs.SessionPath(origSession); sl@0: test(r==KErrNone); sl@0: TFileName file1Path(gLockedBase); sl@0: file1Path+=file1Name; sl@0: TFileName file2Path(file2Name); sl@0: TFileName file3Path(gLockedBase); sl@0: file3Path+=file3Name; sl@0: TFileName file4Path(file4Name); sl@0: // create file that will be used to hang file server sl@0: r=SubFile1.Create(TheFs,file1Path,EFileWrite); sl@0: test(r==KErrNone); sl@0: // create file with same session but on different drive sl@0: RFile subfile2; sl@0: r=subfile2.Create(TheFs,file2Path,EFileWrite); sl@0: test(r==KErrNone); sl@0: // create file on unhung drive and with different session sl@0: RFs fs2; sl@0: r=fs2.Connect(); sl@0: test(r==KErrNone); sl@0: r=fs2.SetSessionPath(origSession); sl@0: test(r==KErrNone); sl@0: RFile subfile3; sl@0: r=subfile3.Create(fs2,file3Path,EFileWrite); sl@0: test(r==KErrNone); sl@0: // create file on unhung drive and with different session sl@0: RFile subfile4; sl@0: r=subfile4.Create(fs2,file4Path,EFileWrite); sl@0: test(r==KErrNone); sl@0: // in a different thread cause the server to hang using one of the File1 subsession sl@0: // put notifier up using TheFs session sl@0: SNonCriticalInfo info={ETrue,ETrue}; sl@0: RThread thread; sl@0: PutNonCriticalNotifier(&info,thread); sl@0: test.Next(_L("test writing to files with hung file server")); sl@0: // check only file4 can be written to sl@0: _LIT8(buffer,"abc"); sl@0: TBuf8<8> buf(buffer); sl@0: // File1 caused hung file server sl@0: r=SubFile1.Write(buf); sl@0: test(r==KErrInUse); sl@0: // file2 is same session as subsession that caused hung file server sl@0: r=subfile2.Write(buf); sl@0: test(r==KErrInUse); sl@0: // file3 is opened on hung drive sl@0: r=subfile3.Write(buf); sl@0: test(r==KErrInUse); sl@0: // file4 should be ok sl@0: r=subfile4.Write(buf); sl@0: test(r==KErrNone); sl@0: // hard to test EFsSubClose since does not return an error value sl@0: test.Next(_L("test closing down the subsessions")); sl@0: subfile4.Close(); sl@0: // calling close on the same subsession as is hung will cause this subsession sl@0: // to be closed once the original request is completed sl@0: SubFile1.Close(); sl@0: subfile2.Close(); sl@0: sl@0: // get rid of non-critical notifier sl@0: test.Printf(_L("Enter %S on the notifier\n"),&KPassword); sl@0: TRequestStatus deathStat; sl@0: thread.Logon( deathStat ); sl@0: HungSemaphoreNC.Wait(); sl@0: test(HungReturnCodeNC==KErrNotFound); sl@0: User::WaitForRequest( deathStat ); sl@0: thread.Close(); sl@0: // close remaining files sl@0: subfile3.Close(); sl@0: // clean up sl@0: fs2.Close(); sl@0: r=TheFs.Delete(file1Path); sl@0: test(r==KErrNone); sl@0: r=TheFs.Delete(file2Path); sl@0: test(r==KErrNone); sl@0: r=TheFs.Delete(file3Path); sl@0: test(r==KErrNone); sl@0: r=TheFs.Delete(file4Path); sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: void TestExtendedNotifier() sl@0: // sl@0: // sl@0: // sl@0: { sl@0: test.Next(_L("TestExtendedNotifier")); sl@0: // setup a notification on a removable media sl@0: test.Next(_L("test with drive specified")); sl@0: TFileName notDir=gLockedBase; sl@0: notDir+=NotifyDir; sl@0: TRequestStatus status; sl@0: TheFs.NotifyChange(ENotifyAll,status,notDir); sl@0: test(status==KRequestPending); sl@0: // now do an operation on c: and test no notification sl@0: TInt r=TheFs.MkDir(NotifyDir); sl@0: test(r==KErrNone); sl@0: r=TheFs.RmDir(NotifyDir); sl@0: test(r==KErrNone); sl@0: User::After(1000000); sl@0: test(status==KRequestPending); sl@0: TheFs.NotifyChangeCancel(status); sl@0: test(status==KErrCancel); sl@0: sl@0: // now put up the notifier sl@0: RThread thread; sl@0: PutNonCriticalNotifier(NULL,thread); sl@0: sl@0: // repeat the above notification sl@0: // setup a notification on a removable media - the drive should be changed sl@0: // to * since notifier is up sl@0: test.Next(_L("test with wildcard for drive")); sl@0: TheFs.NotifyChange(ENotifyAll,status,notDir); sl@0: test(status==KRequestPending); sl@0: // test notification does not go off with wrong path sl@0: r=TheFs.MkDir(NotifyDir2); sl@0: test(r==KErrNone); sl@0: r=TheFs.RmDir(NotifyDir2); sl@0: test(r==KErrNone); sl@0: test(status==KRequestPending); sl@0: // now do an operation on c: and test there has been a notification sl@0: r=TheFs.MkDir(NotifyDir); sl@0: test(r==KErrNone); sl@0: r=TheFs.RmDir(NotifyDir); sl@0: test(r==KErrNone); sl@0: User::After(1000000); sl@0: // request should be completed this time sl@0: test(status==KErrNone); sl@0: sl@0: // set up a notification on drive that is not removable sl@0: // the path should not be changed sl@0: test.Next(_L("test with non-removable drive")); sl@0: TheFs.NotifyChange(ENotifyAll,status,notDir); sl@0: test(status==KRequestPending); sl@0: TRequestStatus status2; sl@0: TFileName origSession; sl@0: r=TheFs.SessionPath(origSession); sl@0: test(r==KErrNone); sl@0: RFs fs2; sl@0: r=fs2.Connect(); sl@0: test(r==KErrNone); sl@0: r=fs2.SetSessionPath(origSession); sl@0: test(r==KErrNone); sl@0: _LIT(notifyDirZ,"z:\\test\\"); sl@0: _LIT(notifyDirSess,"\\test\\"); sl@0: // notifyDirZ already exists, create test dir in session path sl@0: r=fs2.MkDir(notifyDirSess); sl@0: test(r==KErrNone); sl@0: fs2.NotifyChange(ENotifyDir,status2,notifyDirZ); sl@0: test(status2==KRequestPending); sl@0: TRequestStatus status3; sl@0: fs2.NotifyChange(ENotifyDir,status3,notifyDirSess); sl@0: test(status3==KRequestPending); sl@0: // now delete session dir and test no notification sl@0: r=TheFs.RmDir(notifyDirSess); sl@0: test(r==KErrNone); sl@0: test(status2==KRequestPending && status3==KErrNone); sl@0: sl@0: // get rid of non-critical notifier sl@0: test.Printf(_L("Enter %S on the notifier\n"),&KPassword); sl@0: TRequestStatus deathStat; sl@0: thread.Logon( deathStat ); sl@0: HungSemaphoreNC.Wait(); sl@0: test(HungReturnCodeNC==KErrNotFound); sl@0: User::WaitForRequest( deathStat ); sl@0: thread.Close(); sl@0: test(status==KErrNone&&status2==KErrNone); sl@0: fs2.Close(); sl@0: sl@0: test.Next(_L("test extended notification with critical notifier")); sl@0: RThread threadC; sl@0: // put a a critical notifier sl@0: PutCriticalNotifier(ETrue,threadC); sl@0: // setup extended change notification on session path, drive should be changed to * sl@0: TheFs.NotifyChange(ENotifyAll,status,NotifyDir); sl@0: test(status==KRequestPending); sl@0: // get rid of notifier sl@0: test.Printf(_L("Press cancel on for critcal notifier\n")); sl@0: threadC.Logon(deathStat); sl@0: HungSemaphoreC.Wait(); sl@0: User::WaitForRequest(deathStat); sl@0: threadC.Close(); sl@0: // test that notification has not gone off sl@0: test(status==KRequestPending); sl@0: // create directory on locked drive sl@0: r=TheFs.MkDir(notDir); sl@0: test(r==KErrNone); sl@0: // test notifier goes off sl@0: test(status==KErrNone); sl@0: r=TheFs.RmDir(notDir); sl@0: test(r==KErrNone); sl@0: // get rid of critical notifier sl@0: } sl@0: sl@0: LOCAL_C TBool TestSessionPath() sl@0: // sl@0: // sl@0: // sl@0: { sl@0: #if defined(__WINS__) sl@0: TInt r=TheFs.CharToDrive(gSessionPath[0],gSessionDrive); sl@0: test(r==KErrNone); sl@0: if(gSessionDrive==EDriveX) sl@0: return(EFalse); sl@0: #else sl@0: TInt r=TheFs.CharToDrive(gSessionPath[0],gSessionDrive); sl@0: test(r==KErrNone); sl@0: TDriveList list; sl@0: r=TheFs.DriveList(list); sl@0: test(r==KErrNone); sl@0: if((list[gSessionDrive])&KDriveAttRemovable) sl@0: return(EFalse); sl@0: #endif sl@0: return(ETrue); sl@0: } sl@0: sl@0: sl@0: GLDEF_C void CallTestsL() sl@0: // sl@0: // Test a hung file server sl@0: // sl@0: { sl@0: if(!IsTestTypeStandard()) sl@0: return; sl@0: sl@0: if(!TestSessionPath()) sl@0: { sl@0: test.Printf(_L("Not testing on %S\n"),&gSessionPath); sl@0: return; sl@0: } sl@0: #if defined(__WINS__) sl@0: gLockedDrive=EDriveX; sl@0: gLockedPath=_L("?:\\"); sl@0: gLockedBase=_L("?:"); sl@0: gLockedPath[0]=gLockedBase[0]=(TText)('A'+gLockedDrive); sl@0: #else sl@0: gLockedDrive=EDriveD; sl@0: gLockedPath=_L("?:\\"); sl@0: gLockedBase=_L("?:"); sl@0: gLockedPath[0]=gLockedBase[0]=(TText)('A'+gLockedDrive); sl@0: #endif sl@0: sl@0: test.Printf(_L("Is a secure mmc present? Press y for yes\n")); sl@0: TChar c=test.Getch(); sl@0: if(c=='y'||c=='Y') sl@0: isSecureMmc=ETrue; sl@0: else sl@0: isSecureMmc=EFalse; sl@0: sl@0: TInt r=HungSemaphoreC.CreateLocal(0); sl@0: test(r==KErrNone); sl@0: r=HungSemaphoreNC.CreateLocal(0); sl@0: test(r==KErrNone); sl@0: sl@0: // create sharable session sl@0: TheFs.ShareAuto(); sl@0: sl@0: TestParsingFunctions(); sl@0: TestTFsFunctions(); sl@0: TestExtendedNotifier(); sl@0: TestSubsessions(); sl@0: // TestNotifiers(); sl@0: TestCriticalFunctions(); sl@0: TestSameSession(); sl@0: TestSameSubSession(); sl@0: sl@0: HungSemaphoreC.Close(); sl@0: HungSemaphoreNC.Close(); sl@0: }