os/kernelhwsrv/kerneltest/f32test/server/t_hungfs.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// f32test\server\t_hungfs.cpp
sl@0
    15
// this test will either run with a secure mmc or will simulate a
sl@0
    16
// mmc card.
sl@0
    17
// 
sl@0
    18
//
sl@0
    19
sl@0
    20
sl@0
    21
#include <f32file.h>
sl@0
    22
#include <e32test.h>
sl@0
    23
#include "t_server.h"
sl@0
    24
sl@0
    25
GLDEF_D RTest test(_L("T_HUNGFS"));
sl@0
    26
GLREF_D RFs TheFs;
sl@0
    27
sl@0
    28
LOCAL_D RFile SubFile1;
sl@0
    29
LOCAL_D TInt HungReturnCodeC;
sl@0
    30
sl@0
    31
LOCAL_D RSemaphore HungSemaphoreC;
sl@0
    32
LOCAL_D TInt HungReturnCodeNC;
sl@0
    33
LOCAL_D RSemaphore HungSemaphoreNC;
sl@0
    34
sl@0
    35
GLREF_C void Format(TInt aDrive);
sl@0
    36
sl@0
    37
LOCAL_D const TInt KControlIoLockMount=5;
sl@0
    38
LOCAL_D const TInt KControlIoClearLockMount=6;
sl@0
    39
LOCAL_D const TInt KControlIoCNotifier=7;
sl@0
    40
LOCAL_D const TInt KControlIoClearCNotifier=8;
sl@0
    41
sl@0
    42
LOCAL_D const TInt KControlIoCancelNCNotifier=KMaxTInt-1;
sl@0
    43
sl@0
    44
LOCAL_D TBool isSecureMmc;
sl@0
    45
LOCAL_D TFileName gLockedPath;
sl@0
    46
LOCAL_D TFileName gLockedBase;
sl@0
    47
LOCAL_D TInt gLockedDrive;
sl@0
    48
GLREF_D TFileName gSessionPath;
sl@0
    49
LOCAL_D TInt gSessionDrive;
sl@0
    50
sl@0
    51
TBuf8<16> KPassword8=_L8("abc");
sl@0
    52
TBuf16<8> KPassword=_L("abc");
sl@0
    53
_LIT(File1,"file1");
sl@0
    54
_LIT(File2,"file2");
sl@0
    55
_LIT(Dir1,"\\dir1\\");
sl@0
    56
_LIT(NotifyDir,"\\not\\");
sl@0
    57
_LIT(NotifyDir2,"\\abc\\");
sl@0
    58
_LIT(HungDirNC,"\\hungnc\\");
sl@0
    59
_LIT(HungDirC,"\\hungc\\");
sl@0
    60
sl@0
    61
LOCAL_D const TInt KHeapSize=0x2000;
sl@0
    62
sl@0
    63
struct SNonCriticalInfo
sl@0
    64
	{
sl@0
    65
	TBool iSameSession;
sl@0
    66
	TBool iUseRFile;
sl@0
    67
	};
sl@0
    68
sl@0
    69
LOCAL_C TInt ThreadFunctionNC(TAny* aInfo)
sl@0
    70
//
sl@0
    71
// Thread entry point to put up non-critical notifier
sl@0
    72
//
sl@0
    73
	{
sl@0
    74
	RFs fs;
sl@0
    75
	TInt r;
sl@0
    76
sl@0
    77
	TBuf8<8> mmcBuf;
sl@0
    78
	// pad out password if using lockable mmc
sl@0
    79
	if(isSecureMmc)
sl@0
    80
		{
sl@0
    81
		TUint8 pBuf[]={0x61,0x00,0x62,0x00,0x63,00};
sl@0
    82
		mmcBuf.SetLength(6);
sl@0
    83
		for(TInt i=0;i<6;++i)
sl@0
    84
			mmcBuf[i]=pBuf[i];
sl@0
    85
		}
sl@0
    86
sl@0
    87
	SNonCriticalInfo* info=NULL;
sl@0
    88
	if(aInfo!=NULL)
sl@0
    89
		info=(SNonCriticalInfo*)aInfo;
sl@0
    90
sl@0
    91
	r=fs.Connect();
sl@0
    92
	
sl@0
    93
	if(isSecureMmc)
sl@0
    94
		{
sl@0
    95
		if(info && info->iSameSession)
sl@0
    96
			r=TheFs.LockDrive(gLockedDrive,NULL,mmcBuf,EFalse);
sl@0
    97
		else
sl@0
    98
			{
sl@0
    99
			r=fs.LockDrive(gLockedDrive,NULL,mmcBuf,EFalse);
sl@0
   100
			RDebug::Print(_L("l=%d"),r);
sl@0
   101
			}
sl@0
   102
		}
sl@0
   103
	else
sl@0
   104
		{
sl@0
   105
		if(info && info->iSameSession)
sl@0
   106
			r=TheFs.ControlIo(gLockedDrive,KControlIoLockMount,KPassword8);
sl@0
   107
		else
sl@0
   108
			r=fs.ControlIo(gLockedDrive,KControlIoLockMount,KPassword8);
sl@0
   109
		}
sl@0
   110
//	UserSvr::ForceRemountMedia(ERemovableMedia0);
sl@0
   111
	User::After(300000);
sl@0
   112
	HungSemaphoreNC.Signal();
sl@0
   113
sl@0
   114
	TFileName hungDir=gLockedBase;
sl@0
   115
	hungDir+=HungDirNC;
sl@0
   116
	if(info && info->iSameSession)
sl@0
   117
		r=TheFs.RmDir(hungDir);
sl@0
   118
	else if(info && info->iSameSession && info->iUseRFile)
sl@0
   119
		{
sl@0
   120
		TBuf8<16> buf=_L8("abc");
sl@0
   121
		r=SubFile1.Write(buf);
sl@0
   122
		}
sl@0
   123
	else
sl@0
   124
		{
sl@0
   125
		r=fs.RmDir(hungDir);
sl@0
   126
		RDebug::Print(_L("rd=%d"),r);
sl@0
   127
		}
sl@0
   128
	HungReturnCodeNC=r;
sl@0
   129
sl@0
   130
	if(isSecureMmc)
sl@0
   131
		{
sl@0
   132
		r=fs.UnlockDrive(gLockedDrive,mmcBuf,EFalse);
sl@0
   133
		r=fs.ClearPassword(gLockedDrive,mmcBuf);
sl@0
   134
		}
sl@0
   135
	else
sl@0
   136
		r=fs.ControlIo(gLockedDrive,KControlIoClearLockMount,KPassword8);
sl@0
   137
sl@0
   138
	HungSemaphoreNC.Signal();
sl@0
   139
sl@0
   140
	fs.Close();
sl@0
   141
sl@0
   142
	return(KErrNone);
sl@0
   143
	}
sl@0
   144
sl@0
   145
LOCAL_C TInt ThreadFunctionC(TAny* aDrive)
sl@0
   146
//
sl@0
   147
// Thread entry point to put up a critical notifier
sl@0
   148
//
sl@0
   149
	{
sl@0
   150
	RFs fs;
sl@0
   151
	TInt r=fs.Connect();
sl@0
   152
	test(r==KErrNone);
sl@0
   153
	
sl@0
   154
	TInt drive;
sl@0
   155
#if defined(__WINS__)
sl@0
   156
	drive=EDriveY;
sl@0
   157
#else	
sl@0
   158
	drive=EDriveC;
sl@0
   159
#endif
sl@0
   160
	// can only get critcal notifer up using ControIo
sl@0
   161
	// assumes fat file system running on one of the drives named below
sl@0
   162
	r=fs.ControlIo(drive,KControlIoCNotifier);
sl@0
   163
	
sl@0
   164
	TBool isRemovable=*(TBool*)aDrive;
sl@0
   165
	TFileName hungDir=(_L("?:"));
sl@0
   166
#if defined(__WINS__)
sl@0
   167
	if(isRemovable)
sl@0
   168
		hungDir[0]=(TText)('A'+EDriveX);
sl@0
   169
	else
sl@0
   170
		hungDir[0]=(TText)('A'+EDriveY);
sl@0
   171
#else
sl@0
   172
	if(isRemovable)
sl@0
   173
		hungDir[0]=(TText)('A'+EDriveD);
sl@0
   174
	else
sl@0
   175
		hungDir[0]=(TText)('A'+EDriveC);
sl@0
   176
#endif
sl@0
   177
	hungDir+=HungDirC;
sl@0
   178
	r=fs.RmDir(hungDir);
sl@0
   179
	r=fs.MkDir(hungDir);
sl@0
   180
	HungReturnCodeC=r;
sl@0
   181
sl@0
   182
	r=fs.ControlIo(drive,KControlIoClearCNotifier);
sl@0
   183
sl@0
   184
	HungSemaphoreC.Signal();
sl@0
   185
	r=fs.RmDir(hungDir);
sl@0
   186
	fs.Close();
sl@0
   187
	return(KErrNone);
sl@0
   188
	}
sl@0
   189
sl@0
   190
LOCAL_C void PutNonCriticalNotifier(TAny* aInfo,RThread& aThread)
sl@0
   191
//
sl@0
   192
// put up a non-critical notifier on a removable media
sl@0
   193
//
sl@0
   194
	{
sl@0
   195
	TInt r=aThread.Create(_L("ThreadNC"),ThreadFunctionNC,KDefaultStackSize,KMinHeapSize,KMinHeapSize,aInfo);
sl@0
   196
	test(r==KErrNone);	
sl@0
   197
	aThread.SetPriority(EPriorityMore);
sl@0
   198
	aThread.Resume();
sl@0
   199
	HungSemaphoreNC.Wait();
sl@0
   200
	User::After(1000000);
sl@0
   201
sl@0
   202
	}
sl@0
   203
sl@0
   204
LOCAL_C void PutCriticalNotifier(TBool aBool,RThread& aThread)
sl@0
   205
//
sl@0
   206
// put up a critical notifier on the specified drive
sl@0
   207
//
sl@0
   208
	{
sl@0
   209
	TInt r=aThread.Create(_L("ThreadC"),ThreadFunctionC,KDefaultStackSize,KMinHeapSize,KMinHeapSize,&aBool);
sl@0
   210
	test(r==KErrNone);
sl@0
   211
	aThread.SetPriority(EPriorityMore);
sl@0
   212
	aThread.Resume();
sl@0
   213
	User::After(1000000);
sl@0
   214
	}
sl@0
   215
sl@0
   216
void TestNotifiers()
sl@0
   217
//
sl@0
   218
// Test non-critical notifier is cancelled when the critical notifier is put up
sl@0
   219
// Needs to be carried out on platform with password notifier which handles requests
sl@0
   220
// asynchronously and uses CAtaDisk in fat file system on c: drive ie. not internal ram
sl@0
   221
// drive
sl@0
   222
//
sl@0
   223
	{
sl@0
   224
	test.Next(_L("TestNotifiers"));
sl@0
   225
	if(isSecureMmc)
sl@0
   226
		return;
sl@0
   227
	RThread threadNC,threadC;
sl@0
   228
	PutNonCriticalNotifier(NULL,threadNC);
sl@0
   229
	PutCriticalNotifier(EFalse,threadC);
sl@0
   230
	// get rid of critical notifier
sl@0
   231
	test.Printf(_L("Press cancel on for critcal notifier\n"));
sl@0
   232
	test.Printf(_L("Press any character\n"));
sl@0
   233
	test.Getch();
sl@0
   234
	TRequestStatus deathStat;
sl@0
   235
	threadNC.Logon( deathStat );
sl@0
   236
	HungSemaphoreC.Wait();
sl@0
   237
	// test(HungReturnCodeNC==KErrAbort);
sl@0
   238
	TRequestStatus deathStat2;
sl@0
   239
	threadC.Logon(deathStat2);
sl@0
   240
	HungSemaphoreNC.Wait();
sl@0
   241
	//test(HungReturnCodeNC==KErrLocked);
sl@0
   242
	User::WaitForRequest(deathStat2);
sl@0
   243
	threadNC.Close();
sl@0
   244
	threadC.Close();
sl@0
   245
	}
sl@0
   246
sl@0
   247
void TestCriticalFunctions() 
sl@0
   248
//
sl@0
   249
// test that only a subset of functions are supported when the critical notifier is up
sl@0
   250
//
sl@0
   251
	{
sl@0
   252
	test.Next(_L("test functions supported with critical notifier"));
sl@0
   253
	// used for EFsSubClose
sl@0
   254
	RFile file;
sl@0
   255
	TInt r=file.Create(TheFs,File1,EFileShareAny|EFileWrite);
sl@0
   256
	test(r==KErrNone||KErrAlreadyExists);
sl@0
   257
	if(r==KErrAlreadyExists)
sl@0
   258
		{
sl@0
   259
		r=file.Open(TheFs,File1,EFileShareAny|EFileWrite);
sl@0
   260
		test(r==KErrNone);
sl@0
   261
		}
sl@0
   262
	TBuf8<16> buf=_L8("abcdefghijklmnop");
sl@0
   263
	r=file.Write(buf);
sl@0
   264
	test(r==KErrNone);
sl@0
   265
sl@0
   266
	r=TheFs.MkDir(NotifyDir);
sl@0
   267
	test(r==KErrNone);
sl@0
   268
sl@0
   269
	RThread thread;
sl@0
   270
	PutCriticalNotifier(ETrue,thread);
sl@0
   271
sl@0
   272
	// test functions that are supported with critical notifier
sl@0
   273
	// EFsNotifyChange
sl@0
   274
	test.Next(_L("test functions that are supported with critical notifier"));
sl@0
   275
	TRequestStatus status;
sl@0
   276
	TheFs.NotifyChange(ENotifyAll,status);
sl@0
   277
	test(status==KRequestPending);
sl@0
   278
	// EFsNotifyChangeCancel
sl@0
   279
	TheFs.NotifyChangeCancel();
sl@0
   280
	test(status==KErrCancel);
sl@0
   281
	// EFsNotifyChangeEx
sl@0
   282
	TheFs.NotifyChange(ENotifyAll,status,gSessionPath);
sl@0
   283
	test(status==KRequestPending);
sl@0
   284
	// EFsNotifyChangeCancelEx
sl@0
   285
	TheFs.NotifyChangeCancel(status);
sl@0
   286
	test(status==KErrCancel);
sl@0
   287
	// EFsSubClose
sl@0
   288
	// difficult  to test properly because this does not return an error value
sl@0
   289
	file.Close();
sl@0
   290
sl@0
   291
	// test that notifications are not completed when a critical notifier completes
sl@0
   292
	test.Next(_L("test notifications not completed"));
sl@0
   293
	TheFs.NotifyChange(ENotifyDisk,status);
sl@0
   294
	test(status==KRequestPending);
sl@0
   295
	TRequestStatus status2;
sl@0
   296
	TheFs.NotifyChange(ENotifyDir,status2,NotifyDir);
sl@0
   297
	test(status2==KRequestPending);
sl@0
   298
sl@0
   299
	// test some functions that are not supported when critcical notifier up
sl@0
   300
	// EFsFileOpen
sl@0
   301
	test.Next(_L("test functions that are not supported with critical notifier"));
sl@0
   302
	r=file.Open(TheFs,File2,EFileShareAny);
sl@0
   303
	test(r==KErrInUse);
sl@0
   304
	// EFsFileCreate
sl@0
   305
	r=file.Create(TheFs,File2,EFileShareAny);
sl@0
   306
	test(r==KErrInUse);
sl@0
   307
	// EFsMkDir
sl@0
   308
	r=TheFs.MkDir(Dir1);
sl@0
   309
	test(r==KErrInUse);
sl@0
   310
	// EFsVolume
sl@0
   311
	TVolumeInfo info;
sl@0
   312
	r=TheFs.Volume(info,gSessionDrive);
sl@0
   313
	test(r==KErrInUse);
sl@0
   314
sl@0
   315
	// get rid of critical notifier
sl@0
   316
	test.Printf(_L("Press escape on the critical notifier\n"));
sl@0
   317
	TRequestStatus deathStat;
sl@0
   318
	thread.Logon(deathStat);
sl@0
   319
	HungSemaphoreC.Wait();
sl@0
   320
	test(HungReturnCodeC==KErrAbort);
sl@0
   321
	User::WaitForRequest(deathStat);
sl@0
   322
	thread.Close();
sl@0
   323
sl@0
   324
	// test notifiers have not gone off
sl@0
   325
	test(status==KRequestPending&&status2==KRequestPending);
sl@0
   326
sl@0
   327
	// test that notification setup on  default drive has had the drive changed
sl@0
   328
	// to * since the critical notifier was up
sl@0
   329
	TFileName notDir=gLockedBase;
sl@0
   330
	notDir+=NotifyDir;
sl@0
   331
	r=TheFs.MkDir(notDir);
sl@0
   332
	test(r==KErrNone);
sl@0
   333
	test(status==KRequestPending&&status2==KErrNone);
sl@0
   334
	TheFs.NotifyChangeCancel();
sl@0
   335
	test(status==KErrCancel);
sl@0
   336
	r=TheFs.Delete(File1);
sl@0
   337
	test(r==KErrNone);
sl@0
   338
	r=TheFs.RmDir(notDir);
sl@0
   339
	test(r==KErrNone);
sl@0
   340
	r=TheFs.RmDir(NotifyDir);
sl@0
   341
	test(r==KErrNone);
sl@0
   342
	}
sl@0
   343
sl@0
   344
void TestParsingFunctions()	
sl@0
   345
//
sl@0
   346
// Test functions that use Parse* and Validate* functions with 
sl@0
   347
// non-critical notifier up
sl@0
   348
// 
sl@0
   349
	{
sl@0
   350
	test.Next(_L("TestParsingFunctions"));
sl@0
   351
	RThread thread;
sl@0
   352
	PutNonCriticalNotifier(NULL,thread);
sl@0
   353
	
sl@0
   354
	// test on same drive as notifier
sl@0
   355
	test.Next(_L("test parsing functions on same drive"));
sl@0
   356
	// Using ParseSubst
sl@0
   357
	TFileName dir=gLockedBase;
sl@0
   358
	dir+=Dir1;
sl@0
   359
	TInt r=TheFs.MkDir(dir);
sl@0
   360
	test(r==KErrInUse);
sl@0
   361
	TFileName file=gLockedPath;
sl@0
   362
	file+=File1;
sl@0
   363
	RFile f;
sl@0
   364
	r=f.Create(TheFs,file,EFileShareAny);
sl@0
   365
	test(r==KErrInUse);
sl@0
   366
	// Using ParsePathPtr0
sl@0
   367
	r=TheFs.SetSubst(gLockedPath,EDriveO);
sl@0
   368
	test(r==KErrInUse);
sl@0
   369
	// ValidateDrive
sl@0
   370
	TVolumeInfo info;
sl@0
   371
	r=TheFs.Volume(info,gLockedDrive);
sl@0
   372
	test(r==KErrInUse);
sl@0
   373
sl@0
   374
	TFileName origSessPath;
sl@0
   375
	r=TheFs.SessionPath(origSessPath);
sl@0
   376
	test(r==KErrNone);
sl@0
   377
sl@0
   378
	// test these work ok
sl@0
   379
	r=TheFs.SetSessionPath(gLockedPath);
sl@0
   380
	test(r==KErrNone);
sl@0
   381
	r=TheFs.SetSessionPath(origSessPath);
sl@0
   382
	test(r==KErrNone);
sl@0
   383
sl@0
   384
	// test on different drive from notifier - the session path
sl@0
   385
	test.Next(_L("test parsing functions on a different drive"));
sl@0
   386
	// Using ParseSubst
sl@0
   387
	r=TheFs.MkDir(Dir1);
sl@0
   388
	test(r==KErrNone);
sl@0
   389
	r=TheFs.RmDir(Dir1);
sl@0
   390
	test(r==KErrNone);
sl@0
   391
	r=f.Create(TheFs,File1,EFileShareAny);
sl@0
   392
	test(r==KErrNone);
sl@0
   393
	f.Close();
sl@0
   394
	r=TheFs.Delete(File1);
sl@0
   395
	test(r==KErrNone);
sl@0
   396
	// Using ParsePathPtr0
sl@0
   397
	r=TheFs.SetSubst(gSessionPath,EDriveO);
sl@0
   398
	test(r==KErrNone);
sl@0
   399
	r=TheFs.SetSubst(_L(""),EDriveO);
sl@0
   400
	test(r==KErrNone);
sl@0
   401
	// ValidateDrive
sl@0
   402
	r=TheFs.Volume(info,gSessionDrive);
sl@0
   403
	test(r==KErrNone);
sl@0
   404
sl@0
   405
	// get rid of non-critical notifier
sl@0
   406
	test.Printf(_L("Enter %S on the notifier\n"),&KPassword);
sl@0
   407
sl@0
   408
	TRequestStatus deathStat;
sl@0
   409
	thread.Logon( deathStat );
sl@0
   410
	HungSemaphoreNC.Wait();
sl@0
   411
	test(HungReturnCodeNC==KErrNotFound);
sl@0
   412
	User::WaitForRequest( deathStat );
sl@0
   413
	thread.Close();
sl@0
   414
sl@0
   415
//	test.End();
sl@0
   416
	}
sl@0
   417
	
sl@0
   418
void TestTFsFunctions()	
sl@0
   419
//
sl@0
   420
// test functions that do not use the Parse* and Validate* functions
sl@0
   421
//
sl@0
   422
	{
sl@0
   423
	test.Next(_L("TestTFsFunctions"));
sl@0
   424
	TFileName sessName,lockedName;
sl@0
   425
	TInt r=TheFs.FileSystemName(sessName,gSessionDrive);
sl@0
   426
	test(r==KErrNone);
sl@0
   427
	r=TheFs.FileSystemName(lockedName,gLockedDrive);
sl@0
   428
	test(r==KErrNone);
sl@0
   429
sl@0
   430
	RThread thread;
sl@0
   431
	PutNonCriticalNotifier(NULL,thread);
sl@0
   432
sl@0
   433
	// test functions on hung drive - should return KErrInUse
sl@0
   434
	test.Next(_L("test TFs functions on hung drive"));
sl@0
   435
	// TFsDismountFileSystem
sl@0
   436
	r=TheFs.DismountFileSystem(lockedName,gLockedDrive);
sl@0
   437
	test(r==KErrInUse);
sl@0
   438
	// TFsMountFileSystem
sl@0
   439
	r=TheFs.MountFileSystem(lockedName,gLockedDrive);
sl@0
   440
	test(r==KErrInUse);
sl@0
   441
	// TFsFileSystemName
sl@0
   442
	r=TheFs.FileSystemName(lockedName,gLockedDrive);
sl@0
   443
	test(r==KErrInUse);
sl@0
   444
sl@0
   445
	// test functions on drive other than hung drive
sl@0
   446
	test.Next(_L("test TFs functions on drive that is not hung"));
sl@0
   447
	// TFsDismountFileSystem
sl@0
   448
#if defined(__WINS__)
sl@0
   449
	// bug in TFsMountFileSystem which needs to be fixed before running on EDriveC on WINS
sl@0
   450
	if(gSessionDrive!=EDriveC)
sl@0
   451
		{
sl@0
   452
#endif
sl@0
   453
	r=TheFs.DismountFileSystem(sessName,gSessionDrive);
sl@0
   454
	test(r==KErrNone);
sl@0
   455
	// TFsMountFileSystem
sl@0
   456
	r=TheFs.MountFileSystem(sessName,gSessionDrive);
sl@0
   457
	test(r==KErrNone);
sl@0
   458
#if defined(__WINS__)
sl@0
   459
		}
sl@0
   460
#endif
sl@0
   461
	// TFsFileSystemName
sl@0
   462
	TFileName fsName;
sl@0
   463
	r=TheFs.FileSystemName(fsName,gSessionDrive);
sl@0
   464
	test(r==KErrNone);
sl@0
   465
	test(fsName==sessName);
sl@0
   466
sl@0
   467
	// test functions that fail on all drives
sl@0
   468
	test.Next(_L("test TFs functions that fail on all drives"));
sl@0
   469
	// TFsListOpenFiles
sl@0
   470
	CFileList* list=NULL;
sl@0
   471
	TOpenFileScan fileScan(TheFs);
sl@0
   472
	TRAP(r,fileScan.NextL(list));
sl@0
   473
	test(r==KErrInUse);
sl@0
   474
sl@0
   475
	// test functions that should pass on any drive
sl@0
   476
	test.Next(_L("test TFs functions that pass on all drives"));
sl@0
   477
	// TFsSetDefaultPath
sl@0
   478
	// TFsSetSessionPath
sl@0
   479
	r=TheFs.SetSessionPath(gLockedPath);
sl@0
   480
	test(r==KErrNone);
sl@0
   481
	r=TheFs.SetSessionPath(gSessionPath);
sl@0
   482
	test(r==KErrNone);
sl@0
   483
sl@0
   484
	// get rid of non-critical notifier
sl@0
   485
	test.Printf(_L("Enter %S on the notifier\n"),&KPassword);
sl@0
   486
	TRequestStatus deathStat;
sl@0
   487
	thread.Logon( deathStat );
sl@0
   488
	HungSemaphoreNC.Wait();
sl@0
   489
	test(HungReturnCodeNC==KErrNotFound);
sl@0
   490
	User::WaitForRequest( deathStat );
sl@0
   491
	thread.Close();
sl@0
   492
//	test.End();
sl@0
   493
	}
sl@0
   494
sl@0
   495
sl@0
   496
void TestSubsessions()	
sl@0
   497
//
sl@0
   498
// test subsession functions
sl@0
   499
//
sl@0
   500
	{
sl@0
   501
	test.Next(_L("TestSubsessions"));
sl@0
   502
	RThread thread;
sl@0
   503
	PutNonCriticalNotifier(NULL,thread);
sl@0
   504
sl@0
   505
	// test that subsessions cannot be opened on a hung drive
sl@0
   506
	test.Next(_L("test subsessions cannot be opened on a hung drive"));
sl@0
   507
	// EFsFileCreate
sl@0
   508
	RFile file;
sl@0
   509
	TFileName fileName=gLockedPath;
sl@0
   510
	fileName+=File1;
sl@0
   511
	TInt r=file.Create(TheFs,fileName,EFileShareAny);
sl@0
   512
	test(r==KErrInUse);
sl@0
   513
	// EFsFormatOpen
sl@0
   514
	RFormat format;
sl@0
   515
	TInt count;
sl@0
   516
	r=format.Open(TheFs,gLockedPath,EHighDensity,count);
sl@0
   517
	test(r==KErrInUse);
sl@0
   518
	// EFsDirOpen
sl@0
   519
	RDir dir;
sl@0
   520
	r=dir.Open(TheFs,gLockedPath,KEntryAttMaskSupported);
sl@0
   521
	test(r==KErrInUse);
sl@0
   522
	// EFsRawDiskOpen
sl@0
   523
	RRawDisk raw;
sl@0
   524
	r=raw.Open(TheFs,gLockedDrive);
sl@0
   525
	test(r==KErrInUse);
sl@0
   526
sl@0
   527
	// get rid of non-critical notifier
sl@0
   528
	test.Printf(_L("Enter %S on the notifier\n"),&KPassword);
sl@0
   529
	TRequestStatus deathStat;
sl@0
   530
	thread.Logon( deathStat );
sl@0
   531
	HungSemaphoreNC.Wait();
sl@0
   532
	test(HungReturnCodeNC==KErrNotFound);
sl@0
   533
	User::WaitForRequest( deathStat );
sl@0
   534
	thread.Close();
sl@0
   535
sl@0
   536
	// now open the subsessions
sl@0
   537
	r=file.Create(TheFs,fileName,EFileShareAny);
sl@0
   538
	test(r==KErrNone||KErrAlreadyExists);
sl@0
   539
	if(r==KErrAlreadyExists)
sl@0
   540
		{
sl@0
   541
		r=file.Open(TheFs,fileName,EFileShareAny);
sl@0
   542
		test(r==KErrNone);
sl@0
   543
		}
sl@0
   544
	r=dir.Open(TheFs,gLockedPath,KEntryAttMaskSupported);
sl@0
   545
	test(r==KErrNone);
sl@0
   546
	
sl@0
   547
	// put notifier back up
sl@0
   548
	PutNonCriticalNotifier(NULL,thread);
sl@0
   549
sl@0
   550
	// test subsession operations fail on a hung drive
sl@0
   551
	test.Next(_L("test subsession operations fail on a hung drive"));
sl@0
   552
	// EFsFileRead
sl@0
   553
	TBuf8<16> readBuf;
sl@0
   554
	r=file.Read(readBuf);
sl@0
   555
	test(r==KErrInUse);
sl@0
   556
	// subsession should be able to be closed ok
sl@0
   557
	file.Close();
sl@0
   558
	// EFsDelete
sl@0
   559
	r=TheFs.Delete(fileName);
sl@0
   560
	test(r==KErrInUse);
sl@0
   561
	// EFsDirRead
sl@0
   562
	TEntry entry;
sl@0
   563
	r=dir.Read(entry);
sl@0
   564
	test(r==KErrInUse);
sl@0
   565
	// subsession should be able to be closed ok
sl@0
   566
	dir.Close();
sl@0
   567
sl@0
   568
	// not going to test operations on a drive the is not hung
sl@0
   569
	// since this will be tested on other tests
sl@0
   570
sl@0
   571
	// get rid of non-critical notifier
sl@0
   572
	test.Printf(_L("Enter %S on the notifier\n"),&KPassword);
sl@0
   573
	thread.Logon( deathStat );
sl@0
   574
	HungSemaphoreNC.Wait();
sl@0
   575
	test(HungReturnCodeNC==KErrNotFound);
sl@0
   576
	User::WaitForRequest( deathStat );
sl@0
   577
	thread.Close();
sl@0
   578
sl@0
   579
	r=TheFs.Delete(fileName);
sl@0
   580
	test(r==KErrNone);
sl@0
   581
//	test.End();
sl@0
   582
	}
sl@0
   583
sl@0
   584
void TestSameSession()
sl@0
   585
//
sl@0
   586
// Test functions that can and cannot be handled from same session when notifier is up
sl@0
   587
//
sl@0
   588
	{
sl@0
   589
	test.Next(_L("TestSameSession"));
sl@0
   590
sl@0
   591
	RFile file;
sl@0
   592
	TInt r=file.Create(TheFs,File1,EFileWrite);
sl@0
   593
	test(r==KErrNone);
sl@0
   594
sl@0
   595
	// put notifier up using TheFs session
sl@0
   596
	SNonCriticalInfo info={ETrue,0};
sl@0
   597
	RThread thread;
sl@0
   598
	PutNonCriticalNotifier(&info,thread);
sl@0
   599
sl@0
   600
	// test critical functions can be handled
sl@0
   601
	test.Next(_L("test critical functions can be handled"));
sl@0
   602
	// EFsNotifyChange
sl@0
   603
	TRequestStatus status;
sl@0
   604
	TheFs.NotifyChange(ENotifyAll,status);
sl@0
   605
	test(status==KRequestPending);
sl@0
   606
	// EFsNotifyChangeCancel
sl@0
   607
	TheFs.NotifyChangeCancel();
sl@0
   608
	test(status==KErrCancel);
sl@0
   609
	// EFsNotifyChange again
sl@0
   610
	TheFs.NotifyChange(ENotifyAll,status);
sl@0
   611
	test(status==KRequestPending);
sl@0
   612
	// EFsNotifyChangeCancelEx
sl@0
   613
	TheFs.NotifyChangeCancel(status);
sl@0
   614
	test(status==KErrCancel);
sl@0
   615
	// not going to test EFsSubClose
sl@0
   616
sl@0
   617
	// test other functions are not handled
sl@0
   618
	test.Next(_L("test other functions cannot be handled"));
sl@0
   619
	// EFsNotifyChangeEx
sl@0
   620
	TheFs.NotifyChange(ENotifyAll,status,gSessionPath);
sl@0
   621
	test(status==KErrInUse);
sl@0
   622
	TFileName defPath;
sl@0
   623
	// EFsCheckDisk
sl@0
   624
	r=TheFs.CheckDisk(gSessionPath);
sl@0
   625
	test(r==KErrInUse);
sl@0
   626
	// EFsFileWrite
sl@0
   627
	_LIT8(buffer,"abc");
sl@0
   628
	TBuf8<8> buf(buffer);
sl@0
   629
	r=file.Write(buf);
sl@0
   630
	test(r==KErrInUse);
sl@0
   631
sl@0
   632
	// this file should be able to be closed
sl@0
   633
	file.Close();
sl@0
   634
sl@0
   635
	// get rid of non-critical notifier
sl@0
   636
	test.Printf(_L("Enter %S on the notifier\n"),&KPassword);
sl@0
   637
	
sl@0
   638
	TRequestStatus deathStat;
sl@0
   639
	thread.Logon( deathStat );
sl@0
   640
	HungSemaphoreNC.Wait();
sl@0
   641
	test(HungReturnCodeNC==KErrNotFound);
sl@0
   642
	User::WaitForRequest( deathStat );
sl@0
   643
	thread.Close();
sl@0
   644
sl@0
   645
	r=TheFs.Delete(File1);
sl@0
   646
	test(r==KErrNone);
sl@0
   647
//	test.End();
sl@0
   648
	}
sl@0
   649
sl@0
   650
void TestSameSubSession()
sl@0
   651
// 
sl@0
   652
// test hung file server with same subsession
sl@0
   653
//
sl@0
   654
	{
sl@0
   655
	_LIT(file1Name,"\\SubFile1");
sl@0
   656
	_LIT(file2Name,"\\SubFile2");
sl@0
   657
	_LIT(file3Name,"\\SubFile3");
sl@0
   658
	_LIT(file4Name,"\\SubFile4");
sl@0
   659
	TFileName origSession;
sl@0
   660
	TInt r=TheFs.SessionPath(origSession);
sl@0
   661
	test(r==KErrNone);
sl@0
   662
	TFileName file1Path(gLockedBase);
sl@0
   663
	file1Path+=file1Name;
sl@0
   664
	TFileName file2Path(file2Name);
sl@0
   665
	TFileName file3Path(gLockedBase);
sl@0
   666
	file3Path+=file3Name;
sl@0
   667
	TFileName file4Path(file4Name);
sl@0
   668
	// create file that will be used to hang file server
sl@0
   669
	r=SubFile1.Create(TheFs,file1Path,EFileWrite);
sl@0
   670
	test(r==KErrNone);
sl@0
   671
	// create file with same session but on different drive
sl@0
   672
	RFile subfile2;
sl@0
   673
	r=subfile2.Create(TheFs,file2Path,EFileWrite);
sl@0
   674
	test(r==KErrNone);
sl@0
   675
	// create file on unhung drive and with different session
sl@0
   676
	RFs fs2;
sl@0
   677
	r=fs2.Connect();
sl@0
   678
	test(r==KErrNone);
sl@0
   679
	r=fs2.SetSessionPath(origSession);
sl@0
   680
	test(r==KErrNone);
sl@0
   681
	RFile subfile3;
sl@0
   682
	r=subfile3.Create(fs2,file3Path,EFileWrite);
sl@0
   683
	test(r==KErrNone);
sl@0
   684
	// create file on unhung drive and with different session
sl@0
   685
	RFile subfile4;
sl@0
   686
	r=subfile4.Create(fs2,file4Path,EFileWrite);
sl@0
   687
	test(r==KErrNone);
sl@0
   688
	// in a different thread cause the server to hang using one of the File1 subsession
sl@0
   689
	// put notifier up using TheFs session
sl@0
   690
	SNonCriticalInfo info={ETrue,ETrue};
sl@0
   691
	RThread thread;
sl@0
   692
	PutNonCriticalNotifier(&info,thread);
sl@0
   693
	test.Next(_L("test writing to files with hung file server"));
sl@0
   694
	// check only file4 can be written to
sl@0
   695
	_LIT8(buffer,"abc");
sl@0
   696
	TBuf8<8> buf(buffer);
sl@0
   697
	// File1 caused hung file server
sl@0
   698
	r=SubFile1.Write(buf);
sl@0
   699
	test(r==KErrInUse);
sl@0
   700
	// file2 is same session as subsession that caused hung file server
sl@0
   701
	r=subfile2.Write(buf);
sl@0
   702
	test(r==KErrInUse);
sl@0
   703
	// file3 is opened on hung drive
sl@0
   704
	r=subfile3.Write(buf);
sl@0
   705
	test(r==KErrInUse);
sl@0
   706
	// file4 should be ok
sl@0
   707
	r=subfile4.Write(buf);
sl@0
   708
	test(r==KErrNone);
sl@0
   709
	// hard to test EFsSubClose since does not return an error value
sl@0
   710
	test.Next(_L("test closing down the subsessions"));
sl@0
   711
	subfile4.Close();
sl@0
   712
	// calling close on the same subsession as is hung will cause this subsession
sl@0
   713
	// to be closed once the original request is completed
sl@0
   714
	SubFile1.Close();
sl@0
   715
	subfile2.Close();
sl@0
   716
sl@0
   717
	// get rid of non-critical notifier
sl@0
   718
	test.Printf(_L("Enter %S on the notifier\n"),&KPassword);
sl@0
   719
	TRequestStatus deathStat;
sl@0
   720
	thread.Logon( deathStat );
sl@0
   721
	HungSemaphoreNC.Wait();
sl@0
   722
	test(HungReturnCodeNC==KErrNotFound);
sl@0
   723
	User::WaitForRequest( deathStat );
sl@0
   724
	thread.Close();
sl@0
   725
	// close remaining files
sl@0
   726
	subfile3.Close();
sl@0
   727
	// clean up
sl@0
   728
	fs2.Close();
sl@0
   729
	r=TheFs.Delete(file1Path);
sl@0
   730
	test(r==KErrNone);
sl@0
   731
	r=TheFs.Delete(file2Path);
sl@0
   732
	test(r==KErrNone);
sl@0
   733
	r=TheFs.Delete(file3Path);
sl@0
   734
	test(r==KErrNone);
sl@0
   735
	r=TheFs.Delete(file4Path);
sl@0
   736
	test(r==KErrNone);
sl@0
   737
	}
sl@0
   738
sl@0
   739
void TestExtendedNotifier()
sl@0
   740
//
sl@0
   741
//
sl@0
   742
//
sl@0
   743
	{
sl@0
   744
	test.Next(_L("TestExtendedNotifier"));
sl@0
   745
	// setup a notification on a removable media
sl@0
   746
	test.Next(_L("test with drive specified"));
sl@0
   747
	TFileName notDir=gLockedBase;
sl@0
   748
	notDir+=NotifyDir;
sl@0
   749
	TRequestStatus status;
sl@0
   750
	TheFs.NotifyChange(ENotifyAll,status,notDir);
sl@0
   751
	test(status==KRequestPending);
sl@0
   752
	// now do an operation on c: and test no notification
sl@0
   753
	TInt r=TheFs.MkDir(NotifyDir);
sl@0
   754
	test(r==KErrNone);
sl@0
   755
	r=TheFs.RmDir(NotifyDir);
sl@0
   756
	test(r==KErrNone);
sl@0
   757
	User::After(1000000);
sl@0
   758
	test(status==KRequestPending);
sl@0
   759
	TheFs.NotifyChangeCancel(status);
sl@0
   760
	test(status==KErrCancel);
sl@0
   761
sl@0
   762
	// now put up the notifier
sl@0
   763
	RThread thread;
sl@0
   764
	PutNonCriticalNotifier(NULL,thread);
sl@0
   765
sl@0
   766
	// repeat the above notification
sl@0
   767
	// setup a notification on a removable media - the drive should be changed
sl@0
   768
	// to * since notifier is up
sl@0
   769
	test.Next(_L("test with wildcard for drive"));
sl@0
   770
	TheFs.NotifyChange(ENotifyAll,status,notDir);
sl@0
   771
	test(status==KRequestPending);
sl@0
   772
	// test notification does not go off with wrong path
sl@0
   773
	r=TheFs.MkDir(NotifyDir2);
sl@0
   774
	test(r==KErrNone);
sl@0
   775
	r=TheFs.RmDir(NotifyDir2);
sl@0
   776
	test(r==KErrNone);
sl@0
   777
	test(status==KRequestPending);
sl@0
   778
	// now do an operation on c: and test there has been a notification
sl@0
   779
	r=TheFs.MkDir(NotifyDir);
sl@0
   780
	test(r==KErrNone);
sl@0
   781
	r=TheFs.RmDir(NotifyDir);
sl@0
   782
	test(r==KErrNone);
sl@0
   783
	User::After(1000000);
sl@0
   784
	// request should be completed this time
sl@0
   785
	test(status==KErrNone);
sl@0
   786
sl@0
   787
	// set up a notification on drive that is not removable
sl@0
   788
	// the path should not be changed
sl@0
   789
	test.Next(_L("test with non-removable drive"));
sl@0
   790
	TheFs.NotifyChange(ENotifyAll,status,notDir);
sl@0
   791
	test(status==KRequestPending);
sl@0
   792
	TRequestStatus status2;
sl@0
   793
	TFileName origSession;
sl@0
   794
	r=TheFs.SessionPath(origSession);
sl@0
   795
	test(r==KErrNone);
sl@0
   796
	RFs fs2;
sl@0
   797
	r=fs2.Connect();
sl@0
   798
	test(r==KErrNone);
sl@0
   799
	r=fs2.SetSessionPath(origSession);
sl@0
   800
	test(r==KErrNone);
sl@0
   801
	_LIT(notifyDirZ,"z:\\test\\");
sl@0
   802
	_LIT(notifyDirSess,"\\test\\");
sl@0
   803
	// notifyDirZ already exists, create test dir in session path
sl@0
   804
	r=fs2.MkDir(notifyDirSess);
sl@0
   805
	test(r==KErrNone);
sl@0
   806
	fs2.NotifyChange(ENotifyDir,status2,notifyDirZ);
sl@0
   807
	test(status2==KRequestPending);
sl@0
   808
	TRequestStatus status3;
sl@0
   809
	fs2.NotifyChange(ENotifyDir,status3,notifyDirSess);
sl@0
   810
	test(status3==KRequestPending);
sl@0
   811
	// now delete session dir and test no notification
sl@0
   812
	r=TheFs.RmDir(notifyDirSess);
sl@0
   813
	test(r==KErrNone);
sl@0
   814
	test(status2==KRequestPending && status3==KErrNone);
sl@0
   815
sl@0
   816
	// get rid of non-critical notifier
sl@0
   817
	test.Printf(_L("Enter %S on the notifier\n"),&KPassword);
sl@0
   818
	TRequestStatus deathStat;
sl@0
   819
	thread.Logon( deathStat );
sl@0
   820
	HungSemaphoreNC.Wait();
sl@0
   821
	test(HungReturnCodeNC==KErrNotFound);
sl@0
   822
	User::WaitForRequest( deathStat );
sl@0
   823
	thread.Close();
sl@0
   824
	test(status==KErrNone&&status2==KErrNone);
sl@0
   825
	fs2.Close();
sl@0
   826
sl@0
   827
	test.Next(_L("test extended notification with critical notifier"));
sl@0
   828
	RThread threadC;
sl@0
   829
	// put a a critical notifier
sl@0
   830
	PutCriticalNotifier(ETrue,threadC);
sl@0
   831
	// setup extended change notification on session path, drive should be changed to *
sl@0
   832
	TheFs.NotifyChange(ENotifyAll,status,NotifyDir);
sl@0
   833
	test(status==KRequestPending);
sl@0
   834
	// get rid of notifier
sl@0
   835
	test.Printf(_L("Press cancel on for critcal notifier\n"));
sl@0
   836
	threadC.Logon(deathStat);
sl@0
   837
	HungSemaphoreC.Wait();
sl@0
   838
	User::WaitForRequest(deathStat);
sl@0
   839
	threadC.Close();
sl@0
   840
	// test that notification has not gone off
sl@0
   841
	test(status==KRequestPending);
sl@0
   842
	// create directory on locked drive
sl@0
   843
	r=TheFs.MkDir(notDir);
sl@0
   844
	test(r==KErrNone);
sl@0
   845
	// test notifier goes off
sl@0
   846
	test(status==KErrNone);
sl@0
   847
	r=TheFs.RmDir(notDir);
sl@0
   848
	test(r==KErrNone);
sl@0
   849
	// get rid of critical notifier
sl@0
   850
	}	
sl@0
   851
sl@0
   852
LOCAL_C TBool TestSessionPath()
sl@0
   853
//
sl@0
   854
// 
sl@0
   855
//
sl@0
   856
	{
sl@0
   857
#if defined(__WINS__)
sl@0
   858
	TInt r=TheFs.CharToDrive(gSessionPath[0],gSessionDrive);
sl@0
   859
	test(r==KErrNone);
sl@0
   860
	if(gSessionDrive==EDriveX)
sl@0
   861
		return(EFalse);
sl@0
   862
#else
sl@0
   863
	TInt r=TheFs.CharToDrive(gSessionPath[0],gSessionDrive);
sl@0
   864
	test(r==KErrNone);
sl@0
   865
	TDriveList list;
sl@0
   866
	r=TheFs.DriveList(list);
sl@0
   867
	test(r==KErrNone);
sl@0
   868
	if((list[gSessionDrive])&KDriveAttRemovable)
sl@0
   869
		return(EFalse);
sl@0
   870
#endif
sl@0
   871
	return(ETrue);
sl@0
   872
	}
sl@0
   873
sl@0
   874
sl@0
   875
GLDEF_C void CallTestsL()
sl@0
   876
//
sl@0
   877
// Test a hung file server
sl@0
   878
//
sl@0
   879
	{
sl@0
   880
	if(!IsTestTypeStandard())
sl@0
   881
		return;
sl@0
   882
sl@0
   883
	if(!TestSessionPath())
sl@0
   884
		{
sl@0
   885
		test.Printf(_L("Not testing on %S\n"),&gSessionPath);
sl@0
   886
		return;
sl@0
   887
		}
sl@0
   888
#if defined(__WINS__)
sl@0
   889
	gLockedDrive=EDriveX;
sl@0
   890
	gLockedPath=_L("?:\\");
sl@0
   891
	gLockedBase=_L("?:");
sl@0
   892
	gLockedPath[0]=gLockedBase[0]=(TText)('A'+gLockedDrive);
sl@0
   893
#else
sl@0
   894
	gLockedDrive=EDriveD;
sl@0
   895
	gLockedPath=_L("?:\\");
sl@0
   896
	gLockedBase=_L("?:");
sl@0
   897
	gLockedPath[0]=gLockedBase[0]=(TText)('A'+gLockedDrive);
sl@0
   898
#endif
sl@0
   899
sl@0
   900
	test.Printf(_L("Is a secure mmc present? Press y for yes\n"));
sl@0
   901
	TChar c=test.Getch();
sl@0
   902
	if(c=='y'||c=='Y')
sl@0
   903
		isSecureMmc=ETrue;
sl@0
   904
	else
sl@0
   905
		isSecureMmc=EFalse;
sl@0
   906
sl@0
   907
	TInt r=HungSemaphoreC.CreateLocal(0);
sl@0
   908
	test(r==KErrNone);
sl@0
   909
	r=HungSemaphoreNC.CreateLocal(0);
sl@0
   910
	test(r==KErrNone);
sl@0
   911
sl@0
   912
	// create sharable session
sl@0
   913
	TheFs.ShareAuto();
sl@0
   914
sl@0
   915
	TestParsingFunctions();
sl@0
   916
	TestTFsFunctions();
sl@0
   917
	TestExtendedNotifier();
sl@0
   918
	TestSubsessions();
sl@0
   919
//	TestNotifiers();
sl@0
   920
	TestCriticalFunctions();
sl@0
   921
	TestSameSession();
sl@0
   922
	TestSameSubSession();
sl@0
   923
sl@0
   924
	HungSemaphoreC.Close();
sl@0
   925
	HungSemaphoreNC.Close();
sl@0
   926
}