os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_svr.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1995-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
// f32\sfile\sf_svr.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "sf_std.h"
sl@0
    19
#include "sf_cache_man.h"
sl@0
    20
#include "sf_file_cache.h"
sl@0
    21
#include "sf_memory_man.h"
sl@0
    22
sl@0
    23
TInt DoFsSubClose(CFsRequest* aRequest)
sl@0
    24
//
sl@0
    25
// Close a subsession.
sl@0
    26
//
sl@0
    27
	{
sl@0
    28
	const TInt handle(aRequest->Message().Int3());
sl@0
    29
sl@0
    30
	CFsObject* pO=SessionObjectFromHandle(handle,0,aRequest->Session());
sl@0
    31
	if(!pO)
sl@0
    32
		return KErrBadHandle;
sl@0
    33
sl@0
    34
	aRequest->Session()->DecResourceCount();
sl@0
    35
	aRequest->Session()->Handles().Remove(handle,ETrue);
sl@0
    36
sl@0
    37
	// this request has also opened this object, so close it here before it 
sl@0
    38
	// gets to a plugin as a plugin may attempt to open the file/dir itself
sl@0
    39
	aRequest->SetScratchValue64( MAKE_TUINT64(I64HIGH(aRequest->ScratchValue64()), 0));
sl@0
    40
sl@0
    41
	return(KErrNone);
sl@0
    42
	}
sl@0
    43
sl@0
    44
sl@0
    45
TInt TFsSubClose::DoRequestL(CFsRequest* aRequest)
sl@0
    46
//
sl@0
    47
// Close a subsession.
sl@0
    48
//
sl@0
    49
	{
sl@0
    50
sl@0
    51
	// Leave and then panic client with KErrBadHandle if necessary.
sl@0
    52
	CFsObject* pO = SessionObjectFromHandle(aRequest->Message().Int3(),0,aRequest->Session());
sl@0
    53
	if(!pO)
sl@0
    54
		return KErrBadHandle;
sl@0
    55
sl@0
    56
	if(aRequest->Message().Function() == EFsFileSubClose)
sl@0
    57
		{
sl@0
    58
		CFileShare* pShare = (CFileShare*) aRequest->ScratchValue();
sl@0
    59
		
sl@0
    60
		// flush the file cache
sl@0
    61
		CFileCache* fileCache = pShare->File().FileCache();
sl@0
    62
		if (fileCache && fileCache->FlushDirty(aRequest) == CFsRequest::EReqActionBusy)
sl@0
    63
			return CFsRequest::EReqActionBusy;
sl@0
    64
sl@0
    65
		// if any write requests are being fair scheduled, wait for them to complete
sl@0
    66
		if (pShare->RequestInProgress())
sl@0
    67
			return CFsRequest::EReqActionBusy;
sl@0
    68
		}
sl@0
    69
sl@0
    70
	return DoFsSubClose(aRequest);
sl@0
    71
	}
sl@0
    72
sl@0
    73
TInt TFsSubClose::Initialise(CFsRequest* aRequest)
sl@0
    74
//
sl@0
    75
//	Now moved to RequestAllocator::GetRequest 
sl@0
    76
//
sl@0
    77
	{
sl@0
    78
	TInt r = KErrNone;
sl@0
    79
	// Closing a file share may require flushing of dirty data, so deal with this in the drive thread
sl@0
    80
	// in TFsSubClose::DoRequestL(). For other objects (EFsFormatSubClose, EFsDirSubClose, EFsRawSubClose,
sl@0
    81
	// FsPluginSubClose) we may complete the message here.
sl@0
    82
	if(aRequest->FsFunction() == EFsFileSubClose)
sl@0
    83
		{
sl@0
    84
		CFileShare* pShare = (CFileShare*)
sl@0
    85
			SessionObjectFromHandle(aRequest->Message().Int3(), FileShares->UniqueID(), aRequest->Session());
sl@0
    86
sl@0
    87
		if(!pShare)
sl@0
    88
			User::Leave(KErrBadHandle);
sl@0
    89
sl@0
    90
		HBufC* pFileName = pShare->File().FileName().Alloc();
sl@0
    91
		aRequest->SetScratchValue64( MAKE_TUINT64((TUint) pFileName, (TUint) pShare) );
sl@0
    92
		TInt driveNumber = pShare->File().Drive().DriveNumber();
sl@0
    93
		aRequest->SetDriveNumber(driveNumber);
sl@0
    94
		}
sl@0
    95
	
sl@0
    96
	// Define a completion routine so that we can see whether this request is cancelled - 
sl@0
    97
	// if it is we still want to close the subsession (but not bother about flushing dirty data)
sl@0
    98
	r = ((CFsMessageRequest*) aRequest)->PushOperation(TFsSubClose::Complete);
sl@0
    99
	
sl@0
   100
sl@0
   101
sl@0
   102
	return r;
sl@0
   103
	}
sl@0
   104
sl@0
   105
TInt TFsSubClose::Complete(CFsRequest* aRequest)
sl@0
   106
	{
sl@0
   107
	// if LastError() != KErrNone, this implies the request has been cancelled. 
sl@0
   108
	// i.e. TFsSubClose::DoRequestL() has not been called, so we need to call DoFsSubClose() here
sl@0
   109
	if (((CFsMessageRequest*) aRequest)->LastError() != KErrNone)
sl@0
   110
		DoFsSubClose(aRequest);
sl@0
   111
sl@0
   112
	return CFsRequest::EReqActionComplete;
sl@0
   113
	}
sl@0
   114
sl@0
   115
sl@0
   116
TInt TFsNotifyChange::DoRequestL(CFsRequest* aRequest)
sl@0
   117
//
sl@0
   118
//
sl@0
   119
//
sl@0
   120
	{
sl@0
   121
	CStdChangeInfo* notificationInfo=new CStdChangeInfo;
sl@0
   122
	if (notificationInfo==NULL)
sl@0
   123
		return (KErrNoMemory);
sl@0
   124
	const RMessage2& m=aRequest->Message();
sl@0
   125
	notificationInfo->Initialise((TNotifyType)m.Int0(),(TRequestStatus*)m.Ptr1(),m,aRequest->Session());
sl@0
   126
	TInt r=FsNotify::AddChange(notificationInfo,KDriveInvalid);
sl@0
   127
	if(r!=KErrNone)
sl@0
   128
		delete(notificationInfo);
sl@0
   129
	return(r);
sl@0
   130
	}
sl@0
   131
sl@0
   132
sl@0
   133
TInt TFsNotifyChange::Initialise(CFsRequest* /*aRequest*/)
sl@0
   134
//
sl@0
   135
//
sl@0
   136
//
sl@0
   137
	{
sl@0
   138
	return(KErrNone);
sl@0
   139
	}
sl@0
   140
sl@0
   141
TInt TFsNotifyChangeEx::DoRequestL(CFsRequest* aRequest)
sl@0
   142
//
sl@0
   143
//	Set up an extended change notification
sl@0
   144
//
sl@0
   145
	{
sl@0
   146
	TUint notifyType=aRequest->Message().Int0();
sl@0
   147
	if (aRequest->Src().NamePresent())	//	Monitoring a file
sl@0
   148
		{								//	Reject if iNotifyType is ENotifyDir
sl@0
   149
		if (notifyType&ENotifyDir)
sl@0
   150
			return (KErrArgument);
sl@0
   151
		}
sl@0
   152
	CExtChangeInfo* notificationInfo=new CExtChangeInfo;
sl@0
   153
	if (notificationInfo==NULL)
sl@0
   154
		return (KErrNoMemory);
sl@0
   155
/*	TEntry t;
sl@0
   156
	TInt ret=aRequest->Drive()->Entry(aRequest->Src().FullName().Mid(2),t);
sl@0
   157
	if ((ret==KErrNotFound)||(ret==KErrPathNotFound)||(ret==KErrInUse))			
sl@0
   158
	//	Path does not yet exist or drive has been locked - still submit request
sl@0
   159
	//	but mark it as notify all since the client is potentially interested
sl@0
   160
		notifyType=ENotifyAll;	
sl@0
   161
	else if (ret!=KErrNone)		
sl@0
   162
		{
sl@0
   163
		delete notificationInfo;
sl@0
   164
		return(ret);
sl@0
   165
		}*/
sl@0
   166
sl@0
   167
	const RMessage2& m=aRequest->Message();
sl@0
   168
	notificationInfo->Initialise((TNotifyType)notifyType,(TRequestStatus*)m.Ptr2(),m,aRequest->Session(),aRequest->Src().FullName().Mid(2));
sl@0
   169
	TInt drive;
sl@0
   170
	if (aRequest->ScratchValue()!=0)
sl@0
   171
		drive=KDriveInvalid;
sl@0
   172
	else
sl@0
   173
		drive=aRequest->DriveNumber();
sl@0
   174
	TInt ret=FsNotify::AddChange(notificationInfo,drive);
sl@0
   175
	if(ret!=KErrNone)
sl@0
   176
		delete(notificationInfo);
sl@0
   177
	return(ret);
sl@0
   178
	}
sl@0
   179
sl@0
   180
sl@0
   181
TInt TFsNotifyChangeEx::Initialise(CFsRequest* aRequest)
sl@0
   182
	{
sl@0
   183
	//	Establish whether the directory or file to watch actually exists
sl@0
   184
	//	This sets the aSession members iTheName and iTheParse etc
sl@0
   185
	TInt ret=KErrNone;
sl@0
   186
	TBool monitorAllDrives=EFalse;
sl@0
   187
	TFileName notifyPath;
sl@0
   188
	
sl@0
   189
	TRAP(ret,aRequest->ReadL(KMsgPtr1,notifyPath));
sl@0
   190
	if(ret!=KErrNone)
sl@0
   191
		return(ret);
sl@0
   192
	if(notifyPath.Length()==0)
sl@0
   193
		return(KErrArgument);
sl@0
   194
sl@0
   195
	if ((notifyPath[0]==KMatchAny)||(notifyPath[0]==KMatchOne))
sl@0
   196
		{
sl@0
   197
	//	Use the default session drive for now
sl@0
   198
	//	Client has submitted a ? or * for drive
sl@0
   199
		monitorAllDrives=ETrue;
sl@0
   200
		ret=ParseNotificationPath(aRequest,aRequest->Src(),notifyPath);
sl@0
   201
		if (ret!=KErrNone)
sl@0
   202
			return(ret);
sl@0
   203
		}
sl@0
   204
	else
sl@0
   205
		{
sl@0
   206
	//	Client has submitted a single drive to monitor
sl@0
   207
		monitorAllDrives=EFalse;
sl@0
   208
		
sl@0
   209
	    ret = ParseNoWildSubstPtr1(aRequest, aRequest->Src());
sl@0
   210
		if (ret!=KErrNone)
sl@0
   211
			return(ret);
sl@0
   212
		}
sl@0
   213
	aRequest->SetScratchValue(monitorAllDrives);
sl@0
   214
	ret = PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsNotifyChangeEx, __PLATSEC_DIAGNOSTIC_STRING("Extended Change Notifier"));		
sl@0
   215
	return(ret);
sl@0
   216
	}
sl@0
   217
sl@0
   218
TInt TFsNotifyChangeCancel::DoRequestL(CFsRequest* aRequest)
sl@0
   219
//
sl@0
   220
//
sl@0
   221
//
sl@0
   222
	{
sl@0
   223
	FsNotify::CancelChangeSession(aRequest->Session());
sl@0
   224
#if defined(_DEBUG)
sl@0
   225
	FsNotify::CancelDebugSession(aRequest->Session());
sl@0
   226
#endif
sl@0
   227
	return(KErrNone);
sl@0
   228
	}
sl@0
   229
sl@0
   230
sl@0
   231
sl@0
   232
TInt TFsNotifyChangeCancel::Initialise(CFsRequest* /*aRequest*/)
sl@0
   233
//
sl@0
   234
//
sl@0
   235
//
sl@0
   236
	{
sl@0
   237
	return KErrNone;
sl@0
   238
	}
sl@0
   239
sl@0
   240
sl@0
   241
sl@0
   242
TInt TFsNotifyChangeCancelEx::DoRequestL(CFsRequest* aRequest)
sl@0
   243
//
sl@0
   244
//
sl@0
   245
//
sl@0
   246
	{
sl@0
   247
	FsNotify::CancelChangeSession(aRequest->Session(),(TRequestStatus*)aRequest->Message().Ptr0());
sl@0
   248
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   249
	FsNotify::CancelDebugSession(aRequest->Session());
sl@0
   250
#endif
sl@0
   251
	return(KErrNone);
sl@0
   252
	}
sl@0
   253
sl@0
   254
sl@0
   255
sl@0
   256
TInt TFsNotifyChangeCancelEx::Initialise(CFsRequest* /*aRequest*/)
sl@0
   257
//
sl@0
   258
//
sl@0
   259
//
sl@0
   260
	{
sl@0
   261
	return KErrNone;
sl@0
   262
	}
sl@0
   263
sl@0
   264
//
sl@0
   265
// Setup a disk space notification request
sl@0
   266
//
sl@0
   267
TInt TFsNotifyDiskSpace::DoRequestL(CFsRequest *aRequest)
sl@0
   268
	{
sl@0
   269
	//-- first check that the threshold value is correct and is less than the volume size
sl@0
   270
    const TUint64 threshold = aRequest->ScratchValue64();
sl@0
   271
    if(threshold <= 0)
sl@0
   272
        return KErrArgument;
sl@0
   273
sl@0
   274
    //-- get the size of the mounted volume to check that the requested threshold isn't larger than the volume
sl@0
   275
    TUint64 volSz;
sl@0
   276
    TInt r = aRequest->Drive()->MountedVolumeSize(volSz);
sl@0
   277
	if (r!=KErrNone)
sl@0
   278
		return r;
sl@0
   279
sl@0
   280
    if(threshold >= volSz)
sl@0
   281
        return KErrArgument;
sl@0
   282
sl@0
   283
sl@0
   284
    //-- Create the disk space notificator object and append it to the FsNotify queue
sl@0
   285
	CDiskSpaceInfo* info=new CDiskSpaceInfo;
sl@0
   286
	if(info==NULL)
sl@0
   287
		return(KErrNoMemory);
sl@0
   288
	
sl@0
   289
	const RMessage2& m=aRequest->Message();
sl@0
   290
	info->Initialise((TRequestStatus*)m.Ptr2(),m,aRequest->Session(),threshold);
sl@0
   291
	
sl@0
   292
	r=FsNotify::AddDiskSpace(info,aRequest->DriveNumber());
sl@0
   293
	if(r!=KErrNone)
sl@0
   294
		delete info;
sl@0
   295
	
sl@0
   296
	return(r);
sl@0
   297
	}
sl@0
   298
sl@0
   299
sl@0
   300
TInt TFsNotifyDiskSpace::Initialise(CFsRequest *aRequest)
sl@0
   301
//
sl@0
   302
//
sl@0
   303
//
sl@0
   304
	{
sl@0
   305
	TInt r=ValidateDriveDoSubst(aRequest->Message().Int1(),aRequest);
sl@0
   306
	if (r==KErrNone)
sl@0
   307
		{
sl@0
   308
		TInt64 threshold;
sl@0
   309
		TPtr8 tBuf((TUint8*)&threshold,sizeof(TInt64));
sl@0
   310
		aRequest->ReadL(KMsgPtr0,tBuf);
sl@0
   311
		aRequest->SetScratchValue64(threshold);
sl@0
   312
		}
sl@0
   313
	return(r);
sl@0
   314
	}
sl@0
   315
sl@0
   316
TInt TFsNotifyDiskSpaceCancel::DoRequestL(CFsRequest *aRequest)
sl@0
   317
//
sl@0
   318
// Cancel disk space notification
sl@0
   319
//
sl@0
   320
	{
sl@0
   321
	FsNotify::CancelDiskSpaceSession(aRequest->Session(),(TRequestStatus*)aRequest->Message().Ptr0());
sl@0
   322
	return(KErrNone);
sl@0
   323
	}
sl@0
   324
sl@0
   325
sl@0
   326
TInt TFsNotifyDiskSpaceCancel::Initialise(CFsRequest* /*aRequest*/)
sl@0
   327
//
sl@0
   328
//
sl@0
   329
//
sl@0
   330
	{
sl@0
   331
	return(KErrNone);
sl@0
   332
	}
sl@0
   333
sl@0
   334
TInt TFsSynchroniseDriveThread::DoRequestL(CFsRequest* /*aRequest*/)
sl@0
   335
//
sl@0
   336
// This is to ensure that previous message has been handled in drive thread. 
sl@0
   337
//
sl@0
   338
	{
sl@0
   339
	return CFsRequest::EReqActionComplete;
sl@0
   340
	}
sl@0
   341
sl@0
   342
TInt TFsSynchroniseDriveThread::Initialise(CFsRequest *aRequest)
sl@0
   343
//
sl@0
   344
// Set the drive thread.
sl@0
   345
//
sl@0
   346
	{
sl@0
   347
	if(aRequest->Message().Int0() == -1) //If no drive thread then complete the message
sl@0
   348
		{
sl@0
   349
	    return CFsRequest::EReqActionComplete;
sl@0
   350
  		}
sl@0
   351
	TInt r=ValidateDriveDoSubst(aRequest->Message().Int0(),aRequest);
sl@0
   352
	return r;
sl@0
   353
	}
sl@0
   354
sl@0
   355
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   356
EXPORT_C void DebugNotifySessions(TInt aFunction,TInt /*aDrive*/)
sl@0
   357
//
sl@0
   358
//	Notify sessions of a debug event
sl@0
   359
//
sl@0
   360
    {
sl@0
   361
	// Notifying involves memory de-allocation on the file server's heap -
sl@0
   362
	// check if we need to switch heaps.
sl@0
   363
	RAllocator* current_alloc = &User::Heap();
sl@0
   364
	RAllocator* svr_alloc = ServerThreadAllocator;
sl@0
   365
	if (current_alloc != svr_alloc)
sl@0
   366
		User::SwitchHeap(svr_alloc);
sl@0
   367
	FsNotify::HandleDebug(aFunction);
sl@0
   368
	if (current_alloc != svr_alloc)
sl@0
   369
		User::SwitchHeap(current_alloc);
sl@0
   370
    }
sl@0
   371
#else
sl@0
   372
EXPORT_C void DebugNotifySessions(TInt,TInt)
sl@0
   373
//
sl@0
   374
//	Notify sessions of a debug event
sl@0
   375
//
sl@0
   376
    {}
sl@0
   377
#endif
sl@0
   378
sl@0
   379
sl@0
   380
TInt TFsDriveList::DoRequestL(CFsRequest* aRequest)
sl@0
   381
//
sl@0
   382
// Get the current drive list.
sl@0
   383
//
sl@0
   384
	{
sl@0
   385
	TDriveList list(KMaxDrives);
sl@0
   386
sl@0
   387
	const TUint mask = (TUint) aRequest->Message().Int1();
sl@0
   388
	const TUint matchedFlags=  mask & KDriveAttMatchedFlags;  //KDriveAttMatchedFlags = 0xFFF
sl@0
   389
	const TUint matchedAtt = mask & KDriveAttMatchedAtt;	 //KDriveAttMatchedAtt = 0x0FFF0000
sl@0
   390
	
sl@0
   391
	TInt r = ValidateMatchMask(mask);
sl@0
   392
	if(r!=KErrNone) 
sl@0
   393
	 	return r;
sl@0
   394
	
sl@0
   395
	for (TInt i=0;i<KMaxDrives;i++)
sl@0
   396
		{
sl@0
   397
		if(RFs::IsValidDrive(i))
sl@0
   398
			{
sl@0
   399
			const TUint driveAtt= TheDrives[i].Att();
sl@0
   400
			if(matchedFlags != 0 )
sl@0
   401
				{
sl@0
   402
				switch(matchedAtt)
sl@0
   403
					{
sl@0
   404
					case KDriveAttExclude :
sl@0
   405
						{
sl@0
   406
						list[i]= (driveAtt & matchedFlags ) ? (TUint8)0:(TUint8)driveAtt ;
sl@0
   407
						break;
sl@0
   408
						}
sl@0
   409
					case 0:
sl@0
   410
						{
sl@0
   411
						list[i] = (driveAtt & matchedFlags) ? (TUint8)driveAtt:(TUint8)0 ;
sl@0
   412
						break;
sl@0
   413
						}
sl@0
   414
					case KDriveAttExclusive :
sl@0
   415
						{
sl@0
   416
						if(matchedFlags != KDriveAttLogicallyRemovable)
sl@0
   417
							{
sl@0
   418
							list[i] = ((TUint8)driveAtt == matchedFlags)  ? (TUint8)driveAtt:(TUint8)0;
sl@0
   419
							}
sl@0
   420
						else 
sl@0
   421
							{
sl@0
   422
							list[i] = (driveAtt == (matchedFlags | KDriveAttRemovable))  ? (TUint8)driveAtt:(TUint8)0;
sl@0
   423
							}						
sl@0
   424
						break;
sl@0
   425
						}
sl@0
   426
					case KDriveAttExclude | KDriveAttExclusive:
sl@0
   427
						{
sl@0
   428
						if(matchedFlags != KDriveAttLogicallyRemovable)
sl@0
   429
							{
sl@0
   430
							list[i] = ((TUint8)driveAtt == matchedFlags)  ?(TUint8)0:(TUint8)driveAtt;
sl@0
   431
							}
sl@0
   432
						else 
sl@0
   433
							{
sl@0
   434
							list[i] = (driveAtt == (matchedFlags | KDriveAttRemovable))  ? (TUint8)driveAtt:(TUint8)0;
sl@0
   435
							}
sl@0
   436
						break;
sl@0
   437
						}
sl@0
   438
					default:
sl@0
   439
						{
sl@0
   440
						return KErrArgument;
sl@0
   441
						}
sl@0
   442
					}
sl@0
   443
				}
sl@0
   444
			else  //matchedFlags == 0
sl@0
   445
				{
sl@0
   446
				switch(matchedAtt)
sl@0
   447
					{
sl@0
   448
					case 0:
sl@0
   449
						list[i] = (TUint8)0 ;
sl@0
   450
						break;
sl@0
   451
					case KDriveAttAll:
sl@0
   452
						list[i]= (TUint8)driveAtt;
sl@0
   453
						break;
sl@0
   454
					default:   //all other cases are incorrect
sl@0
   455
						return KErrArgument;				
sl@0
   456
					}
sl@0
   457
				}
sl@0
   458
			}
sl@0
   459
		else //r!=KErrNone
sl@0
   460
			{
sl@0
   461
			list[i]=0;
sl@0
   462
			}			
sl@0
   463
		}
sl@0
   464
sl@0
   465
	aRequest->WriteL(KMsgPtr0,list);
sl@0
   466
sl@0
   467
	// Finally, kick off a speculative probe for devices
sl@0
   468
	ProxyDrives->Lock();
sl@0
   469
	TInt idx = ProxyDrives->Count();
sl@0
   470
	while(idx--)
sl@0
   471
		{
sl@0
   472
		CExtProxyDriveFactory* pF = (CExtProxyDriveFactory*)(*ProxyDrives)[idx];
sl@0
   473
		if(pF)
sl@0
   474
			{
sl@0
   475
			pF->AsyncEnumerate();
sl@0
   476
			}
sl@0
   477
		}
sl@0
   478
	ProxyDrives->Unlock();
sl@0
   479
sl@0
   480
	return(KErrNone);
sl@0
   481
	}
sl@0
   482
sl@0
   483
TInt TFsDriveList::Initialise(CFsRequest* /*aRequest*/)
sl@0
   484
//
sl@0
   485
//
sl@0
   486
//
sl@0
   487
	{
sl@0
   488
	return KErrNone;
sl@0
   489
	}
sl@0
   490
sl@0
   491
TInt TFsDrive::DoRequestL(CFsRequest* aRequest)
sl@0
   492
//
sl@0
   493
// Get drive info.
sl@0
   494
//
sl@0
   495
	{
sl@0
   496
	// executed in main thread, therefore lock to ensure that
sl@0
   497
	// dismount cannot occur during request
sl@0
   498
	FsThreadManager::LockDrive(aRequest->DriveNumber());
sl@0
   499
	TDriveInfo info;
sl@0
   500
	aRequest->Drive()->DriveInfo(info);
sl@0
   501
	if(aRequest->SubstedDrive())
sl@0
   502
		info.iDriveAtt=KDriveAttSubsted;
sl@0
   503
	FsThreadManager::UnlockDrive(aRequest->DriveNumber());
sl@0
   504
	TPckgC<TDriveInfo> pInfo(info);
sl@0
   505
	aRequest->WriteL(KMsgPtr0,pInfo);
sl@0
   506
	return(KErrNone);
sl@0
   507
	}
sl@0
   508
sl@0
   509
TInt TFsDrive::Initialise(CFsRequest* aRequest)
sl@0
   510
//
sl@0
   511
//
sl@0
   512
//
sl@0
   513
	{
sl@0
   514
	TInt r=ValidateDriveDoSubst(aRequest->Message().Int1(),aRequest);
sl@0
   515
	return(r);
sl@0
   516
	}
sl@0
   517
sl@0
   518
sl@0
   519
/**
sl@0
   520
    Get volume info.
sl@0
   521
*/
sl@0
   522
TInt TFsVolume::DoRequestL(CFsRequest* aRequest)
sl@0
   523
	{
sl@0
   524
	TVolumeInfo v;
sl@0
   525
    TPckg<TVolumeInfo> pV(v);
sl@0
   526
sl@0
   527
    //-- read TVolumeInfo from the client side, the client may have provided some data to pass to the server and FSY side
sl@0
   528
    aRequest->ReadL(KMsgPtr0,pV);
sl@0
   529
sl@0
   530
    TRequestStatus* pStat = (TRequestStatus*)aRequest->Message().Ptr2();
sl@0
   531
    if(pStat)
sl@0
   532
        {//-- the user called an asynchronous version of the RFs::Volume
sl@0
   533
         //-- indicate that we request free space asynchronously by setting a special flag that we will pass to the FSY
sl@0
   534
        v.iVolSizeAsync = ETrue;
sl@0
   535
        //-- at present the user's request will be completed by file server as the result of TFsVolume operation.
sl@0
   536
        }
sl@0
   537
    else
sl@0
   538
        {
sl@0
   539
        v.iVolSizeAsync = EFalse;    
sl@0
   540
        }
sl@0
   541
    
sl@0
   542
    //-- ask the FSY to provide us its volume information
sl@0
   543
    TInt r=aRequest->Drive()->Volume(v);
sl@0
   544
	
sl@0
   545
    CSessionFs* session=aRequest->Session();
sl@0
   546
	if (r==KErrNone)
sl@0
   547
		{
sl@0
   548
		TDrive* drive = aRequest->Drive();
sl@0
   549
        const TInt driveNumber = drive->DriveNumber();
sl@0
   550
		
sl@0
   551
        if(!session->ReservedAccess(driveNumber))
sl@0
   552
		    {
sl@0
   553
        	const TInt reserve = drive->ReservedSpace();
sl@0
   554
            if(v.iFree <= reserve)
sl@0
   555
                v.iFree = 0;
sl@0
   556
            else
sl@0
   557
                v.iFree -= reserve;
sl@0
   558
            }
sl@0
   559
sl@0
   560
		if(aRequest->SubstedDrive())
sl@0
   561
			v.iDrive.iDriveAtt=KDriveAttSubsted;
sl@0
   562
sl@0
   563
		
sl@0
   564
		
sl@0
   565
        if (drive->IsMounted() && drive->CurrentMount().LocalBufferSupport() == KErrNone && CCacheManagerFactory::CacheManager() != NULL)
sl@0
   566
			v.iFileCacheFlags = TFileCacheSettings::Flags(driveNumber);
sl@0
   567
		else
sl@0
   568
			v.iFileCacheFlags = TFileCacheFlags(0);
sl@0
   569
		
sl@0
   570
        
sl@0
   571
		aRequest->WriteL(KMsgPtr0,pV);
sl@0
   572
		}
sl@0
   573
	
sl@0
   574
    return(r);
sl@0
   575
	}
sl@0
   576
sl@0
   577
TInt TFsVolume::Initialise(CFsRequest* aRequest)
sl@0
   578
//
sl@0
   579
//
sl@0
   580
//
sl@0
   581
	{
sl@0
   582
sl@0
   583
	TInt r=ValidateDriveDoSubst(aRequest->Message().Int1(),aRequest);
sl@0
   584
	return(r);
sl@0
   585
	}
sl@0
   586
sl@0
   587
sl@0
   588
TInt TFsSetVolume::DoRequestL(CFsRequest* aRequest)
sl@0
   589
//
sl@0
   590
// Set the volume name.
sl@0
   591
//
sl@0
   592
	{
sl@0
   593
    TInt r = CheckDiskSpace(0, aRequest);
sl@0
   594
    if(r != KErrNone)
sl@0
   595
        return r;
sl@0
   596
sl@0
   597
	TFileName volumeName;
sl@0
   598
	aRequest->ReadL(KMsgPtr0,volumeName);
sl@0
   599
	if (volumeName.Length()>KMaxVolumeNameLength)	//	KMaxVolumeNameLength = 11 
sl@0
   600
		return(KErrBadName);
sl@0
   601
	
sl@0
   602
    //	Validate name - return KErrBadName if it contains illegal characters such as * ? / | > <
sl@0
   603
	TNameChecker checker(volumeName);
sl@0
   604
	TText badChar;
sl@0
   605
	if (checker.IsIllegalName(badChar))
sl@0
   606
		return(KErrBadName);
sl@0
   607
sl@0
   608
	return(aRequest->Drive()->SetVolume(volumeName));
sl@0
   609
	}
sl@0
   610
sl@0
   611
sl@0
   612
TInt TFsSetVolume::Initialise(CFsRequest* aRequest)
sl@0
   613
//
sl@0
   614
//
sl@0
   615
//
sl@0
   616
	{
sl@0
   617
	TInt r=ValidateDriveDoSubst(aRequest->Message().Int1(),aRequest);
sl@0
   618
	if (r!=KErrNone)
sl@0
   619
		return(r);
sl@0
   620
	if (!KCapFsSetVolume.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Set Volume")))
sl@0
   621
		return KErrPermissionDenied;
sl@0
   622
	return KErrNone;
sl@0
   623
	}
sl@0
   624
sl@0
   625
sl@0
   626
TInt TFsSubst::DoRequestL(CFsRequest* aRequest)
sl@0
   627
//
sl@0
   628
// Get a drive substitution.
sl@0
   629
//
sl@0
   630
	{
sl@0
   631
	TInt r=ValidateDrive(aRequest->Message().Int1(),aRequest);
sl@0
   632
	if(r!=KErrNone)
sl@0
   633
		return(r);
sl@0
   634
	TFileName substName;
sl@0
   635
	__PRINT(_L("aRequest->Drive()->Att()&KDriveAttSubsted"));
sl@0
   636
	__PRINT1(_L("aRequest->Drive()->Subst()"),&aRequest->Drive()->Subst());
sl@0
   637
	if (aRequest->Drive()->IsSubsted())
sl@0
   638
		substName=aRequest->Drive()->Subst();
sl@0
   639
	aRequest->WriteL(KMsgPtr0,substName);
sl@0
   640
	return(KErrNone);
sl@0
   641
	}
sl@0
   642
sl@0
   643
sl@0
   644
TInt TFsSubst::Initialise(CFsRequest* /*aRequest*/)
sl@0
   645
//
sl@0
   646
//
sl@0
   647
//
sl@0
   648
	{
sl@0
   649
	return KErrNone;
sl@0
   650
	}
sl@0
   651
sl@0
   652
sl@0
   653
TInt TFsSetSubst::DoRequestL(CFsRequest* aRequest)
sl@0
   654
//
sl@0
   655
// Set a drive substitution.
sl@0
   656
//
sl@0
   657
	{
sl@0
   658
	TInt r=ValidateDrive(aRequest->Message().Int1(),aRequest);
sl@0
   659
	if (r!=KErrNone)
sl@0
   660
		return(r);
sl@0
   661
	TDrive* pD=aRequest->Drive();
sl@0
   662
	r=ParsePathPtr0(aRequest,aRequest->Src());
sl@0
   663
	if (r!=KErrNone)
sl@0
   664
		return(r);
sl@0
   665
	//TODO: no protection for unsubsting drives (could check substed path if system then only CRoot process can unsubst
sl@0
   666
	if (pD->IsSubsted() && !aRequest->Src().DrivePresent() && !aRequest->Src().PathPresent())
sl@0
   667
		{
sl@0
   668
		delete &pD->Subst();
sl@0
   669
		pD->SetSubst(NULL);
sl@0
   670
		pD->SetAtt(0);
sl@0
   671
		pD->SetSubstedDrive(NULL);
sl@0
   672
		return(KErrNone);
sl@0
   673
		}
sl@0
   674
	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysSetSubst,&KCapFsPriSetSubst,&KCapFsROSetSubst, __PLATSEC_DIAGNOSTIC_STRING("Set Subst"));
sl@0
   675
	if (r!=KErrNone)
sl@0
   676
		return(r);
sl@0
   677
	if (pD->Att()&(KDriveAttLocal|KDriveAttRom|KDriveAttRedirected|KDriveAttSubsted))
sl@0
   678
		return(KErrGeneral);
sl@0
   679
	if (pD==aRequest->Drive())
sl@0
   680
		return(KErrGeneral);
sl@0
   681
	if (aRequest->Drive()->Att()&(KDriveAttRedirected|KDriveAttSubsted))
sl@0
   682
		return(KErrInUse);
sl@0
   683
	HBufC* pS=aRequest->Src().FullName().Alloc();
sl@0
   684
	if (pS==NULL)
sl@0
   685
		return(KErrNoMemory);
sl@0
   686
	__ASSERT_DEBUG(!&pD->SubstedDrive(),Fault(ETFsSetSubstNotNull));
sl@0
   687
	delete &pD->Subst();
sl@0
   688
	pD->SetSubst(pS);
sl@0
   689
	pD->SetSubstedDrive(aRequest->Drive());
sl@0
   690
	pD->SetAtt(KDriveAttSubsted);
sl@0
   691
	return(KErrNone);
sl@0
   692
	}
sl@0
   693
sl@0
   694
TInt TFsSetSubst::Initialise(CFsRequest* aRequest)
sl@0
   695
//
sl@0
   696
//
sl@0
   697
//
sl@0
   698
	{
sl@0
   699
	if (!KCapFsSetSubst.CheckPolicy(aRequest->Message(),__PLATSEC_DIAGNOSTIC_STRING("Set subst")))
sl@0
   700
	    return KErrPermissionDenied;
sl@0
   701
	return KErrNone;
sl@0
   702
	}
sl@0
   703
sl@0
   704
sl@0
   705
TInt TFsRealName::DoRequestL(CFsRequest* aRequest)
sl@0
   706
//
sl@0
   707
// Get the real name of a file.
sl@0
   708
//
sl@0
   709
	{
sl@0
   710
	TInt r=ParseSubstPtr0(aRequest,aRequest->Src());
sl@0
   711
	if (r!=KErrNone)
sl@0
   712
		return(r);
sl@0
   713
	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysRealName,&KCapFsPriRealName, __PLATSEC_DIAGNOSTIC_STRING("Real Name"));
sl@0
   714
	if (r!=KErrNone)
sl@0
   715
		return(r);
sl@0
   716
	TFileName substName;
sl@0
   717
	if (aRequest->Drive()->Att()&KDriveAttRedirected)
sl@0
   718
		substName=aRequest->Drive()->Subst();	//	DANGER?
sl@0
   719
	else
sl@0
   720
		substName=aRequest->Src().Drive();
sl@0
   721
	if ((substName.Length()+aRequest->Src().FullName().Mid(2).Length())>KMaxFileName)
sl@0
   722
		return(KErrBadName);
sl@0
   723
	substName+=aRequest->Src().FullName().Mid(2);
sl@0
   724
	aRequest->WriteL(KMsgPtr1,substName);
sl@0
   725
	return(KErrNone);
sl@0
   726
	}
sl@0
   727
sl@0
   728
TInt TFsRealName::Initialise(CFsRequest* /*aRequest*/)
sl@0
   729
//
sl@0
   730
//
sl@0
   731
//
sl@0
   732
	{
sl@0
   733
	return KErrNone;
sl@0
   734
	}
sl@0
   735
sl@0
   736
TInt TFsDefaultPath::DoRequestL(CFsRequest* aRequest)
sl@0
   737
//
sl@0
   738
// Get the default path.
sl@0
   739
//
sl@0
   740
	{
sl@0
   741
	if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement))
sl@0
   742
		return KErrNotSupported;
sl@0
   743
	else if(PlatSec::ConfigSetting(PlatSec::EPlatSecDiagnotics))
sl@0
   744
		{
sl@0
   745
		//FIXME: to be remove the following when platform is fully secure
sl@0
   746
		RThread tT;
sl@0
   747
		TInt r=aRequest->Message().Client(tT,EOwnerThread);
sl@0
   748
		if(r!=KErrNone)
sl@0
   749
			return r;
sl@0
   750
		RProcess tP;
sl@0
   751
		r=tT.Process(tP);
sl@0
   752
		if(r!=KErrNone)	
sl@0
   753
			{
sl@0
   754
			tT.Close();	
sl@0
   755
			return r;
sl@0
   756
			}
sl@0
   757
		TName n;
sl@0
   758
		n=tP.Name();
sl@0
   759
		TInt b=n.Locate('[');
sl@0
   760
		if (b>=0)
sl@0
   761
			n.SetLength(b);
sl@0
   762
		RDebug::Print(_L("**** API violation: %S should not use DefaultPath()\n"),&n);
sl@0
   763
		tP.Close();
sl@0
   764
		tT.Close();
sl@0
   765
		//FIXME END
sl@0
   766
		aRequest->WriteL(KMsgPtr0,TheDefaultPath);
sl@0
   767
		return(KErrNone);
sl@0
   768
		}
sl@0
   769
	else
sl@0
   770
		{
sl@0
   771
		aRequest->WriteL(KMsgPtr0,TheDefaultPath);
sl@0
   772
		return(KErrNone);
sl@0
   773
		}
sl@0
   774
	}
sl@0
   775
sl@0
   776
TInt TFsDefaultPath::Initialise(CFsRequest* /*aRequest*/)
sl@0
   777
//
sl@0
   778
//
sl@0
   779
//
sl@0
   780
	{
sl@0
   781
	return KErrNone;
sl@0
   782
	}
sl@0
   783
sl@0
   784
TInt TFsSetDefaultPath::DoRequestL(CFsRequest* aRequest)
sl@0
   785
//
sl@0
   786
// Set the default path.
sl@0
   787
//
sl@0
   788
	{
sl@0
   789
	if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement))
sl@0
   790
		return KErrNotSupported;
sl@0
   791
	else if(PlatSec::ConfigSetting(PlatSec::EPlatSecDiagnotics))
sl@0
   792
		{
sl@0
   793
		//FIXME: to be remove the following when platform is fully secure
sl@0
   794
		RThread tT;
sl@0
   795
		TInt r=aRequest->Message().Client(tT,EOwnerThread);
sl@0
   796
		if(r!=KErrNone)
sl@0
   797
			return r;
sl@0
   798
		RProcess tP;
sl@0
   799
		r=tT.Process(tP);
sl@0
   800
		if(r!=KErrNone)	
sl@0
   801
			{
sl@0
   802
			tT.Close();	
sl@0
   803
			return r;
sl@0
   804
			}
sl@0
   805
		TName n;
sl@0
   806
		n=tP.Name();
sl@0
   807
		TInt b=n.Locate('[');
sl@0
   808
		if (b>=0)
sl@0
   809
			n.SetLength(b);
sl@0
   810
		RDebug::Print(_L("**** API violation: %S should not use SetDefaultPath()\n"),&n);
sl@0
   811
		tP.Close();
sl@0
   812
		tT.Close();
sl@0
   813
		//FIXME END
sl@0
   814
		TParse parse;
sl@0
   815
		/*TInt*/ r=ParsePathPtr0(aRequest,parse);	
sl@0
   816
		if (r!=KErrNone && r!=KErrInUse)
sl@0
   817
			return(r);
sl@0
   818
		if (IsIllegalFullName(parse.FullName()))
sl@0
   819
			return(KErrBadName);
sl@0
   820
		TheDefaultPath=parse.FullName();
sl@0
   821
		return(KErrNone);
sl@0
   822
		}
sl@0
   823
	else
sl@0
   824
		{
sl@0
   825
		TParse parse;
sl@0
   826
		TInt r=ParsePathPtr0(aRequest,parse);	
sl@0
   827
		if (r!=KErrNone && r!=KErrInUse)
sl@0
   828
			return(r);
sl@0
   829
		if (IsIllegalFullName(parse.FullName()))
sl@0
   830
			return(KErrBadName);
sl@0
   831
		TheDefaultPath=parse.FullName();
sl@0
   832
		return(KErrNone);
sl@0
   833
		}
sl@0
   834
	}
sl@0
   835
sl@0
   836
sl@0
   837
TInt TFsSetDefaultPath::Initialise(CFsRequest* /*aRequest*/)
sl@0
   838
//
sl@0
   839
//
sl@0
   840
//
sl@0
   841
	{
sl@0
   842
	return KErrNone;
sl@0
   843
	}
sl@0
   844
sl@0
   845
TInt TFsSessionPath::DoRequestL(CFsRequest* aRequest)
sl@0
   846
//
sl@0
   847
// Get the session path
sl@0
   848
//
sl@0
   849
	{
sl@0
   850
	aRequest->WriteL(KMsgPtr0,aRequest->Session()->Path());
sl@0
   851
	return(KErrNone);
sl@0
   852
	}
sl@0
   853
sl@0
   854
TInt TFsSessionPath::Initialise(CFsRequest* /*aRequest*/)
sl@0
   855
//
sl@0
   856
//
sl@0
   857
//
sl@0
   858
	{
sl@0
   859
	return KErrNone;
sl@0
   860
	}
sl@0
   861
sl@0
   862
sl@0
   863
TInt TFsSetSessionPath::DoRequestL(CFsRequest* aRequest)
sl@0
   864
//
sl@0
   865
// Set the session path
sl@0
   866
//
sl@0
   867
	{
sl@0
   868
	TParse parse;
sl@0
   869
	TInt r=ParsePathPtr0(aRequest,parse);	
sl@0
   870
	if (r!=KErrNone && r!=KErrInUse)
sl@0
   871
		return(r);
sl@0
   872
	r=PathCheck(aRequest,parse.FullName().Mid(2),&KCapFsSysSetSessionPath,&KCapFsPriSetSessionPath, __PLATSEC_DIAGNOSTIC_STRING("Set Session Path"));
sl@0
   873
	if (r!=KErrNone)
sl@0
   874
		return(r);
sl@0
   875
	if (IsIllegalFullName(parse.FullName()))
sl@0
   876
		return(KErrBadName);
sl@0
   877
	HBufC* pP=parse.FullName().Alloc();
sl@0
   878
	if (pP==NULL)
sl@0
   879
		return(KErrNoMemory);
sl@0
   880
	delete &aRequest->Session()->Path();
sl@0
   881
	aRequest->Session()->SetPath(pP);
sl@0
   882
	return(KErrNone);
sl@0
   883
	}
sl@0
   884
sl@0
   885
TInt TFsSetSessionPath::Initialise(CFsRequest* /*aRequest*/)
sl@0
   886
//
sl@0
   887
//
sl@0
   888
//
sl@0
   889
	{
sl@0
   890
	return(KErrNone);
sl@0
   891
	}
sl@0
   892
sl@0
   893
sl@0
   894
TInt TFsParse::DoRequestL(CFsRequest* aRequest)
sl@0
   895
//
sl@0
   896
// Parse a file name.
sl@0
   897
//
sl@0
   898
	{
sl@0
   899
	TFileName name;
sl@0
   900
	aRequest->ReadL(KMsgPtr0,name);
sl@0
   901
	TFileName rel;
sl@0
   902
	if (aRequest->Message().Ptr1()!=NULL)
sl@0
   903
		aRequest->ReadL(KMsgPtr1,rel);
sl@0
   904
	TParse p;
sl@0
   905
	TInt r=p.Set(name,&rel,&aRequest->Session()->Path());
sl@0
   906
	if (r==KErrNone)
sl@0
   907
		{
sl@0
   908
		TPckgC<TParse> pP(p);
sl@0
   909
		aRequest->WriteL(KMsgPtr2,pP);
sl@0
   910
		}
sl@0
   911
	return(r);
sl@0
   912
	}
sl@0
   913
sl@0
   914
TInt TFsParse::Initialise(CFsRequest* /*aRequest*/)
sl@0
   915
//
sl@0
   916
//
sl@0
   917
//
sl@0
   918
	{
sl@0
   919
	return KErrNone;
sl@0
   920
	}
sl@0
   921
sl@0
   922
TInt TFsReserveDriveSpace::DoRequestL(CFsRequest* aRequest)
sl@0
   923
//
sl@0
   924
// set reserved value to add to a drives reserved area
sl@0
   925
//	
sl@0
   926
	{
sl@0
   927
	// extract request info
sl@0
   928
	CSessionFs* session=aRequest->Session(); 
sl@0
   929
	TDrive* drive = aRequest->Drive();
sl@0
   930
sl@0
   931
	if(session->ReservedAccess(drive->DriveNumber()))
sl@0
   932
		return KErrInUse;
sl@0
   933
sl@0
   934
	const TInt reserve = aRequest->Message().Int1(); //-- bytes to reserve on the drive
sl@0
   935
sl@0
   936
	// Check if requested reserve space is within the range
sl@0
   937
	if(reserve > KMaxSessionDriveReserved || reserve < 0) 
sl@0
   938
		return KErrArgument;
sl@0
   939
	
sl@0
   940
    const TInt64 threshold = reserve + drive->ReservedSpace(); //-- free bytes on the volume we actually need 
sl@0
   941
    
sl@0
   942
    TInt nRes = drive->RequestFreeSpaceOnMount(threshold);
sl@0
   943
    if(nRes != KErrNone)
sl@0
   944
        return nRes;
sl@0
   945
sl@0
   946
	const TInt current = session->Reserved(drive->DriveNumber()); 
sl@0
   947
	const TInt diff = reserve - current;	
sl@0
   948
	TInt drvReserved = drive->ReservedSpace();
sl@0
   949
	if((drvReserved + diff) > KMaxTotalDriveReserved)
sl@0
   950
		return KErrTooBig;
sl@0
   951
sl@0
   952
	drvReserved += diff;
sl@0
   953
	drive->SetReservedSpace(drvReserved);
sl@0
   954
	return session->SetReserved(drive->DriveNumber(), reserve);
sl@0
   955
sl@0
   956
	}
sl@0
   957
sl@0
   958
TInt TFsReserveDriveSpace::Initialise(CFsRequest* aRequest)
sl@0
   959
//
sl@0
   960
//	Validate drive and set up the session parameters for request
sl@0
   961
//	
sl@0
   962
	{
sl@0
   963
//	if (!KCapFsReserveDriveSpace.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Reserve Drive Space")))
sl@0
   964
//		return KErrPermissionDenied;
sl@0
   965
	TInt drvNumber=aRequest->Message().Int1();
sl@0
   966
	drvNumber=aRequest->Message().Int0();
sl@0
   967
	TInt r=ValidateDrive(aRequest->Message().Int0(),aRequest);	
sl@0
   968
	return(r);
sl@0
   969
	}
sl@0
   970
sl@0
   971
sl@0
   972
TInt TFsGetReserveAccess::DoRequestL(CFsRequest* aRequest)
sl@0
   973
//
sl@0
   974
//	Get reserved access to a drives reserved area first checking that the session has first reserved some space
sl@0
   975
//	
sl@0
   976
	{
sl@0
   977
	CSessionFs* session=aRequest->Session();
sl@0
   978
sl@0
   979
	TInt size=session->Reserved(aRequest->Drive()->DriveNumber());
sl@0
   980
	if(size <= 0)
sl@0
   981
		return KErrPermissionDenied;
sl@0
   982
	else
sl@0
   983
		session->SetReservedAccess(aRequest->Drive()->DriveNumber(),ETrue);
sl@0
   984
	return KErrNone;
sl@0
   985
	}
sl@0
   986
sl@0
   987
TInt TFsGetReserveAccess::Initialise(CFsRequest* aRequest)
sl@0
   988
//
sl@0
   989
//
sl@0
   990
//	
sl@0
   991
	{
sl@0
   992
//	if (!KCapFsGetReserveAccess.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Get Reserve Access")))
sl@0
   993
//		return KErrPermissionDenied;
sl@0
   994
	TInt r=ValidateDrive(aRequest->Message().Int0(),aRequest); 
sl@0
   995
	return(r);
sl@0
   996
	}
sl@0
   997
sl@0
   998
sl@0
   999
TInt TFsReleaseReserveAccess::DoRequestL(CFsRequest* aRequest)
sl@0
  1000
//
sl@0
  1001
//	Remove access for this session to the locked area for a given drive 
sl@0
  1002
//	
sl@0
  1003
	{
sl@0
  1004
	aRequest->Session()->SetReservedAccess(aRequest->Drive()->DriveNumber(),EFalse);
sl@0
  1005
	return KErrNone;
sl@0
  1006
	}
sl@0
  1007
sl@0
  1008
TInt TFsReleaseReserveAccess::Initialise(CFsRequest* aRequest)
sl@0
  1009
//
sl@0
  1010
//
sl@0
  1011
//	
sl@0
  1012
	{
sl@0
  1013
//	if (!KCapFsReleaseReserveAccess.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Release Reserve Access")))
sl@0
  1014
//		return KErrPermissionDenied;
sl@0
  1015
	TInt r=ValidateDrive(aRequest->Message().Int0(),aRequest);	
sl@0
  1016
	return(r);
sl@0
  1017
	}
sl@0
  1018
sl@0
  1019
TInt TFsSetStartupConfiguration::DoRequestL(CFsRequest* aRequest)
sl@0
  1020
//
sl@0
  1021
//  Configure file server according to command and parameters.
sl@0
  1022
//	
sl@0
  1023
    {
sl@0
  1024
    TInt cmd = aRequest->Message().Int0();
sl@0
  1025
sl@0
  1026
    switch (cmd)
sl@0
  1027
    {
sl@0
  1028
    case ELoaderPriority:
sl@0
  1029
    // Set loader thread priority
sl@0
  1030
        {
sl@0
  1031
        TInt r;
sl@0
  1032
        TFullName loaderFullName(RProcess().FullName());
sl@0
  1033
        loaderFullName.Append(_L("::LoaderThread"));
sl@0
  1034
        RThread loader;
sl@0
  1035
        r = loader.Open(loaderFullName);
sl@0
  1036
        if (r != KErrNone)
sl@0
  1037
            return r;
sl@0
  1038
        loader.SetPriority((TThreadPriority)aRequest->Message().Int1());
sl@0
  1039
        loader.Close();
sl@0
  1040
        }
sl@0
  1041
        break;
sl@0
  1042
	case ESetRugged:
sl@0
  1043
		{
sl@0
  1044
        TInt drive = aRequest->Message().Int1();
sl@0
  1045
        TInt r = ValidateDrive(drive, aRequest);
sl@0
  1046
        if (r != KErrNone)
sl@0
  1047
            return r;
sl@0
  1048
        TInt value = aRequest->Message().Int2();
sl@0
  1049
		aRequest->Drive()->SetRugged(value);
sl@0
  1050
		}
sl@0
  1051
		break;
sl@0
  1052
    default:
sl@0
  1053
    	return KErrArgument;
sl@0
  1054
    }
sl@0
  1055
sl@0
  1056
    return KErrNone;
sl@0
  1057
    }
sl@0
  1058
sl@0
  1059
TInt TFsSetStartupConfiguration::Initialise(CFsRequest* aRequest)
sl@0
  1060
//
sl@0
  1061
//  Check SID of message sender. Can be estart only
sl@0
  1062
//	
sl@0
  1063
    {
sl@0
  1064
    if (aRequest->Message().SecureId() != KEstartUidValue)
sl@0
  1065
        return KErrPermissionDenied;
sl@0
  1066
    return KErrNone;
sl@0
  1067
    }
sl@0
  1068
sl@0
  1069
sl@0
  1070
const TInt KinitialChanges = EChangesLocale|EChangesMidnightCrossover|EChangesThreadDeath|EChangesPowerStatus|EChangesSystemTime|EChangesFreeMemory|EChangesOutOfMemory;
sl@0
  1071
sl@0
  1072
CKernEventNotifier* CKernEventNotifier::New(TInt aPriority)
sl@0
  1073
     {
sl@0
  1074
     __PRINT(_L("CKernEventNotifier::New"));
sl@0
  1075
     CKernEventNotifier* self = new CKernEventNotifier(aPriority);
sl@0
  1076
     if (self && (self->iChangeNotifier.Create() != KErrNone))
sl@0
  1077
         delete self, self = NULL;
sl@0
  1078
     return self;
sl@0
  1079
     }
sl@0
  1080
 
sl@0
  1081
CKernEventNotifier::~CKernEventNotifier()
sl@0
  1082
     {
sl@0
  1083
     Cancel();
sl@0
  1084
     iChangeNotifier.Close();
sl@0
  1085
     }
sl@0
  1086
 
sl@0
  1087
void CKernEventNotifier::Start()
sl@0
  1088
     {
sl@0
  1089
     SetActive();
sl@0
  1090
     iChangeNotifier.Logon(iStatus);
sl@0
  1091
     }
sl@0
  1092
 
sl@0
  1093
void CKernEventNotifier::RunL()
sl@0
  1094
     {
sl@0
  1095
     __PRINT(_L("CKernEventNotifier::RunL"));
sl@0
  1096
     iChange = iStatus.Int();
sl@0
  1097
     Start();
sl@0
  1098
     
sl@0
  1099
     /* Avoid being triggered by initial events */
sl@0
  1100
     if (iChange != 0 && (iChange & KinitialChanges) != KinitialChanges)   
sl@0
  1101
         {
sl@0
  1102
         if (iChange & EChangesLocale)
sl@0
  1103
             CKernEventNotifier::LocaleChangeCallback();
sl@0
  1104
         if (iChange & EChangesFreeMemory)
sl@0
  1105
             CKernEventNotifier::FreeMemoryChangeCallback();
sl@0
  1106
         // Add other event capture below this line
sl@0
  1107
         iChange = 0;
sl@0
  1108
         }
sl@0
  1109
     }
sl@0
  1110
 
sl@0
  1111
void CKernEventNotifier::DoCancel()
sl@0
  1112
     {
sl@0
  1113
     iChangeNotifier.LogonCancel();
sl@0
  1114
     }
sl@0
  1115
 
sl@0
  1116
sl@0
  1117
extern TBool FatUtilitiesUpdateDrivesNotified;
sl@0
  1118
extern TBool FatUtilityFunctionsSet;
sl@0
  1119
sl@0
  1120
TInt CKernEventNotifier::LocaleChangeCallback(TAny*)
sl@0
  1121
     {
sl@0
  1122
     __PRINT(_L("CKernEventNotifier::LocaleChangeCallback"));
sl@0
  1123
     
sl@0
  1124
     //-- check if the locale has just been set and the drives are not yet notified about this.
sl@0
  1125
     if(FatUtilityFunctionsSet && !FatUtilitiesUpdateDrivesNotified)
sl@0
  1126
        {//-- notify drives about locale shange, but only once
sl@0
  1127
        for(TInt i=0; i<KMaxDrives; i++)
sl@0
  1128
            {
sl@0
  1129
            TDrive& drive=TheDrives[i];
sl@0
  1130
sl@0
  1131
            if(drive.DriveNumber() >=0 && drive.IsRemovable() && !drive.IsSubsted())
sl@0
  1132
                {
sl@0
  1133
                __PRINT1(_L("CKernEventNotifier::LocaleChangeCallback upd drive: %d"), drive.DriveNumber());
sl@0
  1134
                drive.SetChanged(ETrue);
sl@0
  1135
                }
sl@0
  1136
            }
sl@0
  1137
     
sl@0
  1138
            FatUtilitiesUpdateDrivesNotified = ETrue;
sl@0
  1139
        }
sl@0
  1140
 
sl@0
  1141
     return KErrNone;
sl@0
  1142
     }
sl@0
  1143
sl@0
  1144
TInt TFsQueryVolumeInfoExt::DoRequestL(CFsRequest* aRequest)
sl@0
  1145
	{
sl@0
  1146
	const TInt cmd = aRequest->Message().Int1();
sl@0
  1147
	TInt rel;
sl@0
  1148
sl@0
  1149
    TDrive* pDrive = aRequest->Drive();
sl@0
  1150
sl@0
  1151
    rel = pDrive->CheckMount();
sl@0
  1152
    if(rel != KErrNone)
sl@0
  1153
        return rel;
sl@0
  1154
sl@0
  1155
	switch (cmd)
sl@0
  1156
		{
sl@0
  1157
		
sl@0
  1158
        //-------------------------------------------------
sl@0
  1159
        //-- file system sub type query
sl@0
  1160
        case EFileSystemSubType:
sl@0
  1161
			{
sl@0
  1162
			TFSName name;
sl@0
  1163
			if (pDrive->IsMounted())
sl@0
  1164
				{
sl@0
  1165
				rel = pDrive->CurrentMount().FileSystemSubType(name);
sl@0
  1166
sl@0
  1167
				//-- get the Mount's file system name if the FS subtype query is not supported or there are no subtypes.
sl@0
  1168
                if (rel==KErrNotSupported)
sl@0
  1169
					{
sl@0
  1170
                    pDrive->CurrentMount().FileSystemName(name);
sl@0
  1171
					}
sl@0
  1172
sl@0
  1173
				if (name.Length())
sl@0
  1174
					{
sl@0
  1175
					TPckgBuf<TFSName> pckgBuf(name);
sl@0
  1176
					aRequest->WriteL(KMsgPtr2, pckgBuf);
sl@0
  1177
					return KErrNone;
sl@0
  1178
					}
sl@0
  1179
				else
sl@0
  1180
					{
sl@0
  1181
					return rel;
sl@0
  1182
					}
sl@0
  1183
				}
sl@0
  1184
			else
sl@0
  1185
				{
sl@0
  1186
				return KErrNotReady;
sl@0
  1187
				}
sl@0
  1188
			}
sl@0
  1189
			
sl@0
  1190
		
sl@0
  1191
        //-------------------------------------------------
sl@0
  1192
        //-- this is RFs::VolumeIOParam() query 
sl@0
  1193
        case EIOParamInfo:
sl@0
  1194
			{
sl@0
  1195
			TVolumeIOParamInfo ioInfo;
sl@0
  1196
			// 1. gets block size information via media driver
sl@0
  1197
		    const TInt drive = aRequest->Message().Int0();
sl@0
  1198
		    
sl@0
  1199
		    // validates local drive numbers
sl@0
  1200
		    if(!IsValidLocalDriveMapping(drive))
sl@0
  1201
		    	{
sl@0
  1202
		    	ioInfo.iBlockSize = KErrNotReady;
sl@0
  1203
		    	}
sl@0
  1204
		    else
sl@0
  1205
		    	{
sl@0
  1206
			    // Get media capability
sl@0
  1207
			    TLocalDriveCapsV6Buf capsBuf;
sl@0
  1208
sl@0
  1209
				// is the drive local?
sl@0
  1210
				if (!IsProxyDrive(drive))
sl@0
  1211
					{
sl@0
  1212
					// if not valid local drive, use default values in localDriveCaps
sl@0
  1213
					// if valid local drive and not locked, use TBusLocalDrive::Caps() values
sl@0
  1214
					// if valid drive and locked, hard-code attributes
sl@0
  1215
					rel = GetLocalDrive(drive).Caps(capsBuf);
sl@0
  1216
					}
sl@0
  1217
				else  // this need to be made a bit nicer
sl@0
  1218
					{   
sl@0
  1219
					CExtProxyDrive* pD = GetProxyDrive(drive);
sl@0
  1220
					if(pD)
sl@0
  1221
						rel = pD->Caps(capsBuf);
sl@0
  1222
					else
sl@0
  1223
						rel = KErrNotReady;
sl@0
  1224
					}
sl@0
  1225
sl@0
  1226
			    if (rel != KErrNone)
sl@0
  1227
			    	{
sl@0
  1228
			    	ioInfo.iBlockSize = rel;
sl@0
  1229
			    	}
sl@0
  1230
			    else
sl@0
  1231
			    	{
sl@0
  1232
				    TLocalDriveCapsV6& caps = capsBuf();
sl@0
  1233
					if (caps.iBlockSize)
sl@0
  1234
						{
sl@0
  1235
						ioInfo.iBlockSize = caps.iBlockSize;
sl@0
  1236
						}
sl@0
  1237
					// returns default size (512) when block is not supported by 
sl@0
  1238
					//  underlying media
sl@0
  1239
					else
sl@0
  1240
						{
sl@0
  1241
						ioInfo.iBlockSize = KDefaultVolumeBlockSize;
sl@0
  1242
						}
sl@0
  1243
			    	}
sl@0
  1244
		    	}
sl@0
  1245
sl@0
  1246
			// 2. gets cluster size via mounted file system; Also get Max. file size supported by the file system
sl@0
  1247
			
sl@0
  1248
            ioInfo.iMaxSupportedFileSize = KMaxTUint64; //-- the value for "not supported case"
sl@0
  1249
sl@0
  1250
            if (pDrive->IsMounted())
sl@0
  1251
				{
sl@0
  1252
				rel = pDrive->CurrentMount().FileSystemClusterSize();
sl@0
  1253
				ioInfo.iClusterSize = rel; // return cluster size or an error code if error happened.
sl@0
  1254
				
sl@0
  1255
                pDrive->CurrentMount().GetMaxSupportedFileSize(ioInfo.iMaxSupportedFileSize);
sl@0
  1256
                
sl@0
  1257
                }
sl@0
  1258
			else
sl@0
  1259
				{
sl@0
  1260
				ioInfo.iClusterSize = KErrNotReady;
sl@0
  1261
				}
sl@0
  1262
sl@0
  1263
			// 3. get rec buffer size from estart.txt file
sl@0
  1264
			{
sl@0
  1265
                _LIT8(KLitSectionNameDrive,"Drive%C");
sl@0
  1266
			    ioInfo.iRecReadBufSize = KErrNotSupported;
sl@0
  1267
			    ioInfo.iRecWriteBufSize = KErrNotSupported;
sl@0
  1268
sl@0
  1269
			    TBuf8<8> sectionName;
sl@0
  1270
			    TInt32 bufSize;
sl@0
  1271
			    sectionName.Format(KLitSectionNameDrive, 'A' + drive);
sl@0
  1272
			    // retrieve recommended buffer size information through F32 INI section
sl@0
  1273
			    if (F32Properties::GetInt(sectionName, _L8("RecReadBufSize"), bufSize))
sl@0
  1274
				    {
sl@0
  1275
				    ioInfo.iRecReadBufSize = bufSize;
sl@0
  1276
				    }
sl@0
  1277
			    if (F32Properties::GetInt(sectionName, _L8("RecWriteBufSize"), bufSize))
sl@0
  1278
				    {
sl@0
  1279
				    ioInfo.iRecWriteBufSize = bufSize;
sl@0
  1280
				    }
sl@0
  1281
			    
sl@0
  1282
			    // packaging and returning results
sl@0
  1283
			    TPckgBuf<TVolumeIOParamInfo> pckgBuf(ioInfo);
sl@0
  1284
			    aRequest->WriteL(KMsgPtr2, pckgBuf);
sl@0
  1285
			}
sl@0
  1286
sl@0
  1287
			// always return KErrNone as error codes are packaged and returned via ioInfo members
sl@0
  1288
			return KErrNone;
sl@0
  1289
			} //case EIOParamInfo:
sl@0
  1290
sl@0
  1291
            //-------------------------------------------------
sl@0
  1292
            //-- check if the specified drive is synchronous or not
sl@0
  1293
            case EIsDriveSync:
sl@0
  1294
            {
sl@0
  1295
                const TInt drive = aRequest->Message().Int0();
sl@0
  1296
                const TBool bDrvSynch = FsThreadManager::IsDriveSync(drive, EFalse);
sl@0
  1297
                TPckgBuf<TBool> buf(bDrvSynch);
sl@0
  1298
                aRequest->WriteL(KMsgPtr2, buf);
sl@0
  1299
                
sl@0
  1300
                return KErrNone;
sl@0
  1301
            }
sl@0
  1302
sl@0
  1303
            //-------------------------------------------------
sl@0
  1304
            //-- query if the drive is finalised
sl@0
  1305
            case EIsDriveFinalised:
sl@0
  1306
            {
sl@0
  1307
                TBool bFinalised;
sl@0
  1308
                TInt nRes = pDrive->CurrentMount().IsMountFinalised(bFinalised);
sl@0
  1309
                if(nRes != KErrNone)
sl@0
  1310
                    return nRes;
sl@0
  1311
sl@0
  1312
                TPckgBuf<TBool> buf(bFinalised);
sl@0
  1313
                aRequest->WriteL(KMsgPtr2, buf);
sl@0
  1314
sl@0
  1315
                return KErrNone;
sl@0
  1316
            }
sl@0
  1317
sl@0
  1318
            
sl@0
  1319
		default:
sl@0
  1320
			{
sl@0
  1321
			return KErrNotSupported;
sl@0
  1322
			}
sl@0
  1323
		}
sl@0
  1324
	}
sl@0
  1325
	
sl@0
  1326
TInt TFsQueryVolumeInfoExt::Initialise(CFsRequest* aRequest)
sl@0
  1327
	{
sl@0
  1328
	TInt r = ValidateDriveDoSubst(aRequest->Message().Int0(),aRequest);
sl@0
  1329
	return r;
sl@0
  1330
	}
sl@0
  1331
sl@0
  1332
TInt CKernEventNotifier::FreeMemoryChangeCallback()
sl@0
  1333
	{
sl@0
  1334
	__PRINT(_L("CKernEventNotifier::FreeMemoryChangeCallback"));
sl@0
  1335
 
sl@0
  1336
	TBool belowThreshold = (iChange & EChangesLowMemory)?(TBool)ETrue:(TBool)EFalse;
sl@0
  1337
	CCacheManager* manager = CCacheManagerFactory::CacheManager();
sl@0
  1338
	if (manager)
sl@0
  1339
		{
sl@0
  1340
		manager->FreeMemoryChanged(belowThreshold);
sl@0
  1341
sl@0
  1342
		// start flushing all dirty data
sl@0
  1343
		if (belowThreshold)
sl@0
  1344
			{
sl@0
  1345
			Files->Lock();
sl@0
  1346
			TInt count=Files->Count();
sl@0
  1347
			while(count--)
sl@0
  1348
				{
sl@0
  1349
				CFileCB* file = (CFileCB*)(*Files)[count];
sl@0
  1350
				if (file->FileCache())
sl@0
  1351
					// Cannot report errors here
sl@0
  1352
					// coverity [unchecked_value]
sl@0
  1353
					(void)file->FileCache()->FlushDirty();
sl@0
  1354
				}
sl@0
  1355
			Files->Unlock();
sl@0
  1356
			}
sl@0
  1357
		}
sl@0
  1358
sl@0
  1359
#ifdef	SYMBIAN_ENABLE_FAT_DIRECTORY_OPT
sl@0
  1360
	CCacheMemoryManager* cacheMemManager = CCacheMemoryManagerFactory::CacheMemoryManager();
sl@0
  1361
	if (cacheMemManager)
sl@0
  1362
		cacheMemManager->FreeMemoryChanged(belowThreshold);
sl@0
  1363
#endif //#ifdef	SYMBIAN_ENABLE_FAT_DIRECTORY_OPT
sl@0
  1364
sl@0
  1365
	return KErrNone;
sl@0
  1366
	}
sl@0
  1367