userlibandfileserver/fileserver/sfile/sf_notifier.cpp
changeset 299 b5a01337d018
parent 31 56f325a607ea
--- a/userlibandfileserver/fileserver/sfile/sf_notifier.cpp	Tue Oct 26 12:49:20 2010 +0100
+++ b/userlibandfileserver/fileserver/sfile/sf_notifier.cpp	Mon Nov 01 20:11:36 2010 +0000
@@ -24,20 +24,21 @@
 CFsPool<CFsNotificationBlock>* FsNotificationManager::iPool;
 
 
-CFsNotificationPathFilter* CFsNotificationPathFilter::NewL(const TDesC& aPath, const TDesC& aFilename)
+CFsNotificationPathFilter* CFsNotificationPathFilter::NewL(const TDesC& aPath, const TDesC& aFilename, TInt aDriveNum)
 	{
 	CFsNotificationPathFilter* self = new (ELeave) CFsNotificationPathFilter();
 	CleanupStack::PushL(self);
-	self->ConstructL(aPath,aFilename);
+	self->ConstructL(aPath,aFilename,aDriveNum);
 	CleanupStack::Pop(self);
 	return self;
 	}
 
-void CFsNotificationPathFilter::ConstructL(const TDesC& aPath, const TDesC& aFilename)
+void CFsNotificationPathFilter::ConstructL(const TDesC& aPath, const TDesC& aFilename, TInt aDriveNum)
 	{
 	//Allocate the path and filename
 	iPath = aPath.AllocL();
 	iFilename = aFilename.AllocL();	
+	iDriveNum = aDriveNum;
 	}
 
 CFsNotificationPathFilter::~CFsNotificationPathFilter()
@@ -176,7 +177,7 @@
 			if(filterTypeCount)
 				{
 				//Remove this type from the filter register
-				TFsNotification::TFsNotificationType type = FsNotificationHelper::NotificationType(filterType);
+				TFsNotification::TFsNotificationType type = CFsNotificationInfo::NotificationType(filterType);
 				FsNotificationManager::SetFilterRegister(type,EFalse,filterTypeCount);
 				}
 			filterList.Reset();
@@ -188,8 +189,6 @@
 		currentDriveFilters = (TFsNotificationTypeDriveArray*)iterator.NextValue();
 		}
 	iDrivesTypesFiltersMap.Close();
-	iPathFilterList.ResetAndDestroy();
-	iPathFilterList.Close();
 	return KErrNone;
 	}
 
@@ -197,10 +196,8 @@
 	{
 	__PRINT(_L("CFsNotifyRequest::AddFilterL"));
 
-	iPathFilterList.AppendL(aFilter);
-	
 	//Get the drive number to so know which drive array to add the filter(s) to.
-	TInt driveNum = FsNotificationHelper::DriveNumber(aFilter->iPath->Des()); 
+	TInt driveNum = aFilter->iDriveNum; 
 	
 	TInt notifyType = 1; 
 	TInt r = KErrNone;
@@ -213,7 +210,7 @@
 			TFsNotificationTypeFilter typeFilter;
 			typeFilter.iNotificationType = (TFsNotification::TFsNotificationType) notifyType;
 			typeFilter.iPathFilter = aFilter;
-			TInt index = FsNotificationHelper::TypeToIndex(typeFilter.iNotificationType);
+			TInt index = CFsNotificationInfo::TypeToIndex(typeFilter.iNotificationType);
 			
 			//If the per-drive-filterLists have not
 			//been set up yet then do so now.
@@ -256,6 +253,11 @@
 	return iClientMsg.Handle();
 	}
 
+const RMessage2& CFsNotifyRequest::BufferMessage()
+    {
+    return iBufferMsg;
+    }
+
 void CFsNotifyRequest::CloseNotification()
 	{
 	__PRINT(_L("CFsNotifyRequest::CloseNotification()"));
@@ -328,7 +330,7 @@
 			User::LeaveIfError(iChainLock.CreateLocal());	
 			}
 		iNotifyRequests = TheContainer->CreateL();
-		iPool = CFsPool<CFsNotificationBlock>::New(KNotificationPoolSize);
+		iPool = CFsPool<CFsNotificationBlock>::New(KNotificationPoolSize,CFsNotificationBlock::New);
 		User::LeaveIfNull(iPool);
 		}
 	}
@@ -336,7 +338,7 @@
 void FsNotificationManager::SetFilterRegister(TUint aFilter, TBool aAdd, TInt aCount)
 	{
 	__PRINT2(_L("FsNotificationManager::SetFilterRegister(aFilter=%u,aAdd=%d)"),aFilter,aAdd);
-	TInt index = FsNotificationHelper::TypeToIndex((TFsNotification::TFsNotificationType)aFilter);
+	TInt index = CFsNotificationInfo::TypeToIndex((TFsNotification::TFsNotificationType)aFilter);
 	TInt& fr = FsNotificationManager::FilterRegister(index);
 	__ASSERT_DEBUG((aAdd) ? fr >= 0 : fr > 0,Fault(ENotificationFault));
 	fr+= aAdd ? aCount : -aCount; 
@@ -400,9 +402,9 @@
 	}
 
 //Get the notification type based on the TFsMessage function
-void FsNotificationHelper::NotificationType(TInt aFunction,TFsNotification::TFsNotificationType& aNotificationType)
+void CFsNotificationInfo::NotificationType(TInt aFunction,TNotificationType& aNotificationType)
 	{
-	__PRINT(_L("FsNotificationHelper::NotificationType"));
+	__PRINT(_L("CFsNotificationInfo::NotificationType"));
 	switch(aFunction)
 		{
 		case EFsFileWrite:
@@ -486,258 +488,7 @@
 	}
 
 
-//=====FsNotificationManager===========================
  
-//Get the path of the file, folder or drive name based on the TFsMessage function
-void FsNotificationHelper::PathName(CFsClientMessageRequest& aRequest, TDes& aPath)
-	{
-	__PRINT(_L("FsNotificationHelper::PathName"));
-	//Get the notification type
-	TInt function = aRequest.Operation()->Function();
-	
-	//Get the filename(s)
-	switch(function)
-		{
-		case EFsFileWrite:			//EParseSrc | EFileShare
-		case EFsFileSetSize:		//EParseSrc | EFileShare
-		case EFsFileSetAtt:			//EParseDst | EParseSrc, - should not use these; has share.
-		case EFsFileSet:
-		case EFsFileWriteDirty:		//EFileShare
-			{
-			CFileShare* share = NULL;
-			CFileCB* file = NULL;
-			GetFileFromScratch(&aRequest,share,file);	
-			aPath.Append(file->DriveNumber() + 'A');
-			aPath.Append(':');
-			aPath.Append(file->FileName().Des());
-			break;
-			}
-		case EFsFileCreate:			//EParseSrc
-		case EFsDelete:				//EParseSrc
-		case EFsSetEntry:			//EParseSrc,
-		case EFsFileRename:			//EParseDst | EParseSrc,
-		case EFsRename:				//EParseDst | EParseSrc,
-		case EFsReplace:			//EParseDst | EParseSrc,
-		case EFsFileReplace:		//EParseSrc
-			{
-			aPath.Copy(aRequest.Src().FullName());
-			break;
-			}
-        case EFsRmDir:              //EParseSrc
-        case EFsMkDir:              //EParseSrc
-            {
-            aPath.Copy(aRequest.Src().DriveAndPath());
-            break;
-            }
-		case EFsFormatNext:			//EParseSrc
-		case EFsDismountFileSystem: //0
-		case EFsMountFileSystem:	//0
-		case EFsSetVolume:			//0
-		case EFsSetDriveName:		//ESync
-		case EFsRawDiskWrite:		//EParseSrc
-		case EFsMountFileSystemScan:
-			{
-			_LIT(KFormatDrive,"?:");
-			TBuf<2> drive;
-			drive.Append(KFormatDrive);
-			drive[0] = TText(aRequest.Drive()->DriveNumber() + 'A');
-			aPath.Copy(drive);
-			break;
-			}
-		default:
-			ASSERT(0);
-			break;
-		}
-	}
-
-//Get the new path of the file, folder or drive name based on the TFsMessage function
-void FsNotificationHelper::NewPathName(CFsClientMessageRequest& aRequest, TPtrC& aNewPath)
-	{
-	__PRINT(_L("FsNotificationHelper::NewPathName"));
-	//Get the notification type
-	TInt function = aRequest.Operation()->Function();
-
-	//Get the filename(s)
-	switch(function)
-		{
-		case EFsFileRename:			//EParseDst | EParseSrc,
-		case EFsRename:				//EParseDst | EParseSrc,
-		case EFsReplace:			//EParseDst | EParseSrc,
-			{
-			aNewPath.Set(aRequest.Dest().FullName());
-			break;
-			}
-		case EFsSetDriveName:		//ESync
-			{
-			TFileName name;
-			aRequest.ReadL(KMsgPtr1, name);
-			aNewPath.Set(name);
-			break;
-			}
-		case EFsSetVolume:			//0
-			{
-			TFileName name;
-			aRequest.ReadL(KMsgPtr0, name);
-			aNewPath.Set(name);
-			break;
-			}
-		default:
-			{
-			ASSERT(0);
-			break;
-			}
-		}
-	}
-
-//Get the size of the notification based on its type
-TInt FsNotificationHelper::NotificationSize(CFsClientMessageRequest& aRequest, TFsNotification::TFsNotificationType aNotificationType, const TDesC& aName)
-	{
-	__PRINT(_L("FsNotificationHelper::NotificationSize"));
-	
-	/*
-	 * If there are no new names, the order of the data in the buffer is:
-	 * Word1   : NotificationSize (2 bytes) , PathSize (2 bytes)
-	 * Word2   : NotificationType (Lower 2 bytes)
-	 * Word(s) : Path (TText8) , [Any sub-class members]
-	 * 
-	 * Else for notification types ERename, EVolumeName and EDriveName the order is:
-	 * Word1   : NotificationSize (2 bytes) , PathSize (2 bytes)
-	 * Word2   : NewNameSize (2 bytes) , NotificationType (2 bytes)
-	 * Word(s) : Path (TText8) , NewName (TText8)
-	 * 
-	 * EOverflow size: KNotificationHeaderSize
-	 */	
-	
-	TInt size = KNotificationHeaderSize + Align4(aName.Size());
-	
-	switch(aNotificationType)
-		{
-		//NewName
- 		case TFsNotification::ERename:
-		case TFsNotification::EVolumeName:
-		case TFsNotification::EDriveName:
-			{
-			TPtrC dest;
-			NewPathName(aRequest,dest);
-			size += Align4(dest.Size()); 
-			break;
-			}
-		case TFsNotification::EFileChange:
-			{
-			size += sizeof(TInt64);
-			break;
-			}
-		case TFsNotification::EAttribute:
-			{
-			size += sizeof(TUint64);
-			break;
-			}
-		case TFsNotification::ECreate: 
-		case TFsNotification::EDelete:
-		case TFsNotification::EMediaChange:
-			{
-			break;
-			}
-		default:
-			{
-			ASSERT(0);
-			break;
-			}
-		}
-	return (TUint16) size;
-	}
-
-TFsNotification::TFsNotificationType FsNotificationHelper::NotificationType(TInt& aIndex)
-	{
-	__PRINT(_L("FsNotificationHelper::NotificationType(TInt)"));
-	__ASSERT_DEBUG(aIndex < KNumRegisterableFilters, Fault(ENotificationFault));
-	
-	switch(aIndex) //No break statements here on purpose
-		{
-		case 7 : return TFsNotification::EMediaChange;
-		case 6 : return TFsNotification::EDriveName;
-		case 5 : return TFsNotification::EVolumeName;
-		case 4 : return TFsNotification::EDelete;
-		case 3 : return TFsNotification::EAttribute;
-		case 2 : return TFsNotification::ECreate;
-		case 1 : return TFsNotification::ERename;
-		case 0 : return TFsNotification::EFileChange;
-		default: ASSERT(0); return (TFsNotification::TFsNotificationType) 0;
-		}
-	}
-
-//Get the array index of the notification based on its type
-TInt FsNotificationHelper::TypeToIndex(TFsNotification::TFsNotificationType aType)
-	{
-	__PRINT(_L("FsNotificationHelper::ArrayIndex"));
-
-	TInt index = 0; 
-	switch(aType) //No break statements here on purpose
-		{
-		case TFsNotification::EMediaChange: index++;
-		case TFsNotification::EDriveName:	index++;
-		case TFsNotification::EVolumeName:	index++;
-		case TFsNotification::EDelete:	 	index++;
-		case TFsNotification::EAttribute:	index++;
-		case TFsNotification::ECreate:	 	index++;
-		case TFsNotification::ERename:	 	index++;
-		case TFsNotification::EFileChange:	// skip;
-		default: break;
-		}
-	__ASSERT_DEBUG(index < KNumRegisterableFilters, Fault(ENotificationFault));
-	return index;
-	}
-
-TInt FsNotificationHelper::DriveNumber(const TPtrC& aPath)
-	{
-	if(aPath.Length() >= 2 && ((TChar)aPath[1])==(TChar)':')
-		{
-		TChar driveChar = ((TChar)aPath[0]);
-		driveChar.UpperCase();
-		TInt driveNum = driveChar-(TChar)'A'; 
-		return driveNum;
-		}
-	else
-		{
-		return KErrNotFound;
-		}
-	}
-
-//Get the attributes set and cleared
-void FsNotificationHelper::Attributes(CFsClientMessageRequest& aRequest, TUint& aSet, TUint& aClear)
-	{
-	__PRINT(_L("FsNotificationHelper::Attributes"));
-
-	TInt function = aRequest.Operation()->Function();
-	const RMessage2& msg = aRequest.Message();
-
-	switch(function)
-		{
-		case EFsFileSet:
-			{
-			aSet = msg.Int1();
-			aClear = msg.Int2();
-			break;
-			}
-		case EFsFileSetAtt:
-			{
-			aSet = msg.Int0();
-			aClear = msg.Int1();
-			break;
-			}
-		case EFsSetEntry:
-			{
-			aSet = msg.Int2();
-			aClear = msg.Int3();
-			break;
-			}
-		default:
-			{
-			ASSERT(0);
-			break;
-			}
-		}
-	}
 
 
 TBool CFsNotifyRequest::ValidateNotification(TInt aNotificationSize, TInt& aServerTail)
@@ -898,7 +649,7 @@
 // If there is a iClientMsg then this is the first time this
 // has been called since the client called RequestNotifications.
 // In this situation we complete the client request.
-TInt CFsNotifyRequest::NotifyChange(CFsClientMessageRequest* aRequest,const TDesC& aName, TFsNotification::TFsNotificationType aNotificationType, CFsNotificationBlock& aBlock)
+TInt CFsNotifyRequest::NotifyChange(CFsNotificationInfo* aRequest, CFsNotificationBlock& aBlock)
 	{
 	/*
 	 * Different notification types have different data associated with them.
@@ -920,8 +671,8 @@
 	
 	__PRINT(_L("CFsNotifyRequest::NotifyChange()"));
 
-	TInt notificationSize = FsNotificationHelper::NotificationSize(*aRequest,aNotificationType,aName);
-	
+    TInt notificationSize = CFsNotificationInfo::NotificationSize(*aRequest);
+    
 	iClientSyncLock.Wait();
 	iTailSemaphore.Wait();
 	
@@ -936,16 +687,23 @@
 	//We can store the size of the notification 
 	//and the size of the name in the same word.
 	
+	TBuf<2> driveBuf;
+	driveBuf.SetLength(2);
+    TChar driveLetter = 'A';
+    RFs::DriveToChar(aRequest->DriveNumber(),driveLetter);
+    driveBuf[0] = (TText)driveLetter;
+    driveBuf[1] = (TText)':';
+	
 	TUint16 nameLen = 0;	//Overflow has no name
 	TInt notifSize = KNotificationHeaderSize;
 	if(!overflow)
 		{
-		nameLen = (TUint16)aName.Size();
+        nameLen = (TUint16)aRequest->SourceSize();
 		notifSize = notificationSize;
 		}
 	else 
 		{
-		aNotificationType = TFsNotification::EOverflow;
+        aRequest->NotificationType() = TFsNotification::EOverflow;
 		}	
 
 	iServerTail = tail + notifSize;
@@ -958,62 +716,47 @@
 	memcpy((TText8*)aBlock.Data()+writeOffset,&sizeNameLen,sizeof(TUint));
 	writeOffset+=sizeof(TUint);
 
-	TPtrC newName;
-	
-	if (aNotificationType == TFsNotification::ERename ||
-		aNotificationType == TFsNotification::EVolumeName ||
-		aNotificationType == TFsNotification::EDriveName)
-		{
-		FsNotificationHelper::NewPathName(*aRequest,newName);
-		//Store NewNameSize and notification Type (Word2)
-		TUint typeNewNameLen = ((TUint16)newName.Size() << 16) | (TUint16)aNotificationType;
+    if (aRequest->NotificationType() == TFsNotification::ERename ||
+        aRequest->NotificationType() == TFsNotification::EVolumeName ||
+        aRequest->NotificationType() == TFsNotification::EDriveName)
+        {
+        //Store NewNameSize and notification Type (Word2)
+        TUint typeNewNameLen = ((TUint16)aRequest->NewNameSize() << 16) | (TUint16)aRequest->NotificationType();
 		memcpy((TText8*)aBlock.Data()+writeOffset,&typeNewNameLen,sizeof(TUint));
 		}
 	else
 		{
 		//Store notification Type (Word2)
-		memcpy((TText8*)aBlock.Data()+writeOffset,&aNotificationType,sizeof(TUint));
+        memcpy((TText8*)aBlock.Data()+writeOffset,&aRequest->NotificationType(),sizeof(TUint));
 		}
 	writeOffset+=sizeof(TUint);
 	
-	CFileShare* share = NULL;
-    CFileCB* file = NULL;
-    if(aRequest) //Don't always have a request such as when called from localdrives.
-        {
-        GetFileFromScratch(aRequest, share, file);
-        }
-    
     //
     //Store UID
-    /*
-	TUid uid;
-	uid.iUid = KErrUnknown;
-	if(aRequest && aRequest->Operation()->iFunction == EFsFileWriteDirty)
-	    {
-	    uid = aRequest->iUID;
-	    }
-	else if(aRequest)
-	    {
-	    uid = aRequest->Message().Identity();
-	    }
-	memcpy((TText8*)aBlock.Data()+writeOffset,&uid.iUid,sizeof(TUint32));
+	memcpy((TText8*)aBlock.Data()+writeOffset,&aRequest->Uid().iUid,sizeof(TUint32));
 	writeOffset+=sizeof(TUint32);
-	*/
+	
 	
 	if(!overflow)
 		{
 		//Store Name (Word3)
-		memcpy((TText8*)aBlock.Data()+writeOffset,aName.Ptr(),aName.Size());
-		writeOffset += Align4(aName.Size());
-		
+	    {
+	    //Store driveColon
+	    if(aRequest->NotificationType()!=TFsNotification::EMediaChange)
+	        {
+	        memcpy((TText8*)aBlock.Data()+writeOffset,driveBuf.Ptr(),driveBuf.Size());
+	        writeOffset += driveBuf.Size(); //NB: Not Align4'd deliberately.
+	        }
+	    memcpy((TText8*)aBlock.Data()+writeOffset,aRequest->Source().FullName().Ptr(),aRequest->Source().FullName().Size());
+	    writeOffset += Align4(aRequest->Source().FullName().Size());
+	    }
 
-		switch (aNotificationType)
+        switch (aRequest->NotificationType())
 			{
 			case TFsNotification::EFileChange:
+			case TFsNotification::EAttribute:
 				{
-				TInt64 size = 0;
-				size = file->CachedSize64();
-				memcpy((TText8*)aBlock.Data()+writeOffset,&size,sizeof(TInt64));
+                memcpy((TText8*)aBlock.Data()+writeOffset,aRequest->Data(),sizeof(TInt64));
 				writeOffset += sizeof(TInt64);
 				break;
 				}
@@ -1022,20 +765,19 @@
 			case TFsNotification::EDriveName:
 				{
 				//Store NewName
-				memcpy((TText8*)aBlock.Data()+writeOffset,newName.Ptr(),newName.Size());
-				writeOffset += Align4(newName.Size());
+				
+				if(!aRequest->DestDriveIsSet())
+				    {
+				    //This means that the notification has come from a Mount rather than from FileServer
+				    //It also means that the new name will have the same drive letter as the source.
+				    memcpy((TText8*)aBlock.Data()+writeOffset,driveBuf.Ptr(),driveBuf.Size());
+				    writeOffset += driveBuf.Size(); //NB: Not Align4'd deliberately.
+				    }
+                memcpy((TText8*)aBlock.Data()+writeOffset,aRequest->NewName().FullName().Ptr(),aRequest->NewName().FullName().Size());
+                writeOffset += Align4(aRequest->NewName().FullName().Size());
 				break;
 				}
-			case TFsNotification::EAttribute:
-				{
-				TUint set=0;
-				TUint clear=0;
-				FsNotificationHelper::Attributes(*aRequest,set,clear);
-				TUint64 att = MAKE_TUINT64(set,clear);
-				memcpy((TText8*)aBlock.Data()+writeOffset,&att,sizeof(TUint64));
-				writeOffset += sizeof(TUint64);
-				break;
-				}
+
 			default:
 				{
 				break;
@@ -1085,107 +827,71 @@
 //A change has occurred in f32 represented by this
 //request object. Work out which CfsNotify’s are interested
 // (if any) and call CfsNotifyRequest::NotifyChange.
-void FsNotificationManager::HandleChange(CFsClientMessageRequest* aRequest,const TDesC& aOperationName, TFsNotification::TFsNotificationType aType)
-	{
-	__PRINT2(_L("FsNotificationManager::HandleChange() aRequest=0x%x, aType=%d"),&aRequest,aType);
-
-	Lock(); //ToDo: Read Lock (Read/Write Lock)	
-	if(Count())
-		{
-		//Only search while there are filters of this type set up.
-		TInt index = FsNotificationHelper::TypeToIndex(aType);
-		TInt& filterCount = FsNotificationManager::FilterRegister(index);
-		TInt seenFilter = filterCount; //Number of requests set up for this type
-		
-		//Iterate CFsNotifyRequests
-		TInt count = iNotifyRequests->Count();
-		
-		if(aType == TFsNotification::EMediaChange)
-			seenFilter = count;
-		
-		//If there aren't any requests then breakout
-		if(count == 0)
-			{
-			Unlock();
-			return;
-			}
-		
-		TInt driveNum = FsNotificationHelper::DriveNumber(aOperationName); 
+void FsNotificationManager::HandleChange(CFsNotificationInfo& aRequest)
+    {
+    __PRINT2(_L("FsNotificationManager::HandleChange() aNotificationInfo=0x%x,NotificationType=%d"),&aRequest,aRequest.NotificationType());
+    if(Count())
+        {
+        Lock(); //ToDo: Read Lock (Read/Write Lock) 
+        if(Count())
+            {
+            //Only search while there are filters of this type set up.
+            TInt index = CFsNotificationInfo::TypeToIndex(aRequest.NotificationType());
+            TInt& filterCount = FsNotificationManager::FilterRegister(index);
+            TInt seenFilter = filterCount; //Number of requests set up for this type
+            
+            //Iterate CFsNotifyRequests
+            TInt count = iNotifyRequests->Count();
+            
+            if(aRequest.NotificationType() == TFsNotification::EMediaChange)
+                seenFilter = count;
+            
+            //If there aren't any requests then breakout
+            if(count == 0)
+                {
+                Unlock();
+                return;
+                }
+            
+            //For every notification request(i.e. every CFsNotify client-side).
+            for(TInt i=0; i<count && seenFilter; ++i)
+                {
+                CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)(*iNotifyRequests)[i];
+                CFsNotifyRequest::TNotifyRequestStatus status = notifyRequest->ActiveStatus();
+                if(! (status==CFsNotifyRequest::EActive || 
+                      status==CFsNotifyRequest::EOutstanding))
+                    {
+                    //Not active; check next notification request
+                    continue;
+                    }
+                
+                //Check whether we are interested in this change.
+                //Get the filters associated with this operation on this drive
+                TFsNotificationTypeArray* filterList = notifyRequest->FilterTypeList(aRequest.DriveNumber(),index);
+                DoHandleChange(filterList,seenFilter,aRequest,notifyRequest);
 
-		//For every notification request.
-		for(TInt i=0; i<count && seenFilter; ++i)
-			{
-			CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)(*iNotifyRequests)[i];
-			CFsNotifyRequest::TNotifyRequestStatus status = notifyRequest->ActiveStatus();
-			if(! (status==CFsNotifyRequest::EActive || 
-				  status==CFsNotifyRequest::EOutstanding))
-				{
-				//Not active; check next notification request
-				continue;
-				}
-			
-			//Check whether we are interested in this change.
-			//Get the filters associated with this operation on this drive
-			TFsNotificationTypeArray* filterList = notifyRequest->FilterTypeList(driveNum,index);
-			DoHandleChange(filterList,seenFilter,aRequest,notifyRequest,aOperationName,aType);
-
-			if(aType==TFsNotification::EMediaChange)
-				continue; //next request
-			
-			//If there are still filters to check
-			if(seenFilter)
-				{
-				//Check changes that are not tied to a particular drive
-				filterList = notifyRequest->FilterTypeList(KErrNotFound,index);
-				DoHandleChange(filterList,seenFilter,aRequest,notifyRequest,aOperationName,aType);
-				}
-			}
-		}
-	Unlock();
-	}
-
-//A change has occurred in f32 represented by this
-//request object. Work out which CfsNotify’s are interested
-// (if any) and call CfsNotifyRequest::NotifyChange.
-void FsNotificationManager::HandleChange(CFsClientMessageRequest& aRequest, TFsNotification::TFsNotificationType aType)
-	{
-	__PRINT(_L("FsNotificationManager::HandleChange"));
-	TFileName currentOperationsName;
-	FsNotificationHelper::PathName(aRequest, currentOperationsName);
-	if(currentOperationsName.Length())
-		HandleChange(&aRequest,currentOperationsName,aType);
-	}
-
-//A change has occurred in f32 represented by this
-//request object. Work out which CfsNotify’s are interested
-// (if any) and call CfsNotifyRequest::NotifyChange.
-void FsNotificationManager::HandleChange(CFsClientMessageRequest& aRequest)
-	{
-	if(Count() && aRequest.Message().Handle() != KLocalMessageHandle)
-		{
-		__PRINT(_L("FsNotificationManager::HandleChange"));
-		TFsNotification::TFsNotificationType operationNotificationType;
-		FsNotificationHelper::NotificationType(aRequest.FsFunction(), operationNotificationType);
-		HandleChange(aRequest,operationNotificationType);
-		}
-	}
+                if(aRequest.NotificationType()==TFsNotification::EMediaChange)
+                    continue; //next request
+                
+                //If there are still filters to check
+                if(seenFilter)
+                    {
+                    //Check changes that are not tied to a particular drive
+                    filterList = notifyRequest->FilterTypeList(KErrNotFound,index);
+                    DoHandleChange(filterList,seenFilter,aRequest,notifyRequest);
+                    }
+                }
+            }
+        Unlock();
+        }
+    }
 
 
 ////
 #else
 ////
 
-void FsNotificationManager::HandleChange(CFsClientMessageRequest* ,const TDesC&, TFsNotification::TFsNotificationType)
-	{
-	return;
-	}
-
-void FsNotificationManager::HandleChange(CFsClientMessageRequest& , TFsNotification::TFsNotificationType)
-	{
-	return;
-	}
-
-void FsNotificationManager::HandleChange(CFsClientMessageRequest&)
+void FsNotificationManager::HandleChange(CFsNotificationInfo&)
 	{
 	return;
 	}
@@ -1193,10 +899,11 @@
 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
 
 //Called from FsNotificationManager::DoHandleChange
-FsNotificationManager::TFsNotificationFilterMatch FsNotificationManager::DoMatchFilter(CFsClientMessageRequest* aRequest, const TDesC& aOperationName,CFsNotificationPathFilter& aFilter)
+FsNotificationManager::TFsNotificationFilterMatch FsNotificationManager::DoMatchFilter(const RMessage2& aMessage, const TDesC& aOperationName,CFsNotificationPathFilter& aFilter)
     {
     TFsNotificationFilterMatch filterMatch = EDifferent;
     TParsePtrC parseOp(aOperationName);
+    
     TPtrC pathOpDes = parseOp.DriveAndPath();
     TPtrC nameOpDes = parseOp.NameAndExt();
     TInt pathLength = aFilter.iPath->Des().Length();
@@ -1210,7 +917,7 @@
     else //if no path filter was set up
         // then we need to ensure we don't notify on data-caged areas which we shouldn't
         {
-        TInt r = PathCheck(aRequest,aOperationName.Mid(2),&KCapFsSysFileTemp,&KCapFsPriFileTemp,&KCapFsROFileTemp, __PLATSEC_DIAGNOSTIC_STRING("FsNotificationManager::DoHandleChange"));
+        TInt r = PathCheck(aMessage,aOperationName.Mid(2),&KCapFsSysFileTemp,&KCapFsPriFileTemp,&KCapFsROFileTemp, __PLATSEC_DIAGNOSTIC_STRING("FsNotificationManager::DoHandleChange"));
         if(r != KErrNone)
             return EContinue; //next filter
         }
@@ -1228,8 +935,9 @@
     return filterMatch;
     }
 
-// This is called on a per drive basis.
-void FsNotificationManager::DoHandleChange(TFsNotificationTypeArray* aFilterTypeArray,TInt& aSeenFilter, CFsClientMessageRequest* aRequest, CFsNotifyRequest* aNotifyRequest, const TDesC& aOperationName, TFsNotification::TFsNotificationType& aType)
+// The aFilterTypeArray is an array for the filters that target the current drive (only).
+// This is called on a per client (CFsNotify) basis.
+void FsNotificationManager::DoHandleChange(TFsNotificationTypeArray* aFilterTypeArray,TInt& aSeenFilter, CFsNotificationInfo& aNotificationInfo, CFsNotifyRequest* aNotifyRequest)
 	{		
 	__PRINT(_L("FsNotificationManager::DoHandleChange()"));
 	
@@ -1238,36 +946,39 @@
 	
 	TInt numFilters = aFilterTypeArray->Count();
 	
-	if(aType == TFsNotification::EMediaChange)
-		numFilters = 1; //Only need to notify once per drive.
-		
-	//For every filter in this request
+    if(aNotificationInfo.NotificationType() == TFsNotification::EMediaChange)
+        numFilters = 1; //Only need to notify once per client for EMediaChange.
+        
+    //For every filter in this request (CFsNotify)
 	for(TInt j = 0; j < numFilters;++j)
 		{
 		//Is the correct notification type
 		aSeenFilter--;
 		
 		TBool filterMatch = EDifferent;
-		if(aType != TFsNotification::EMediaChange)
+        if(aNotificationInfo.NotificationType()  != TFsNotification::EMediaChange)
 			{
 			CFsNotificationPathFilter& filter = *(((*aFilterTypeArray)[j]).iPathFilter);
-			__PRINT2(_L("FsNotificationManager::DoHandleChange() operationName=%S, filterName=%S"),&aOperationName,filter.iPath);
-			
-			filterMatch = DoMatchFilter(aRequest,aOperationName,filter);
+            __PRINT2(_L("FsNotificationManager::DoHandleChange() operationName=%S, filterName=%S"),&aNotificationInfo.Source().FullName(),filter.iPath);
+            
+			//buferMsg here is the message of the client *recieving* the notification
+            const RMessage2& bufferMsg = aNotifyRequest->BufferMessage();
+            filterMatch = DoMatchFilter(bufferMsg,aNotificationInfo.Source().FullName(),filter);
 			if(filterMatch == FsNotificationManager::EContinue)
 			    continue; //triggers for data cages
 			
 			//We need to check for changes coming in to a directory when its rename
-			if(aType == TFsNotification::ERename && filterMatch==FsNotificationManager::EDifferent)  
+            if(aNotificationInfo.NotificationType() == TFsNotification::ERename && filterMatch==FsNotificationManager::EDifferent)  
                 {
-                TPtrC aDestinationNamePtrC;
-                FsNotificationHelper::NewPathName(*aRequest,aDestinationNamePtrC);
-                __PRINT2(_L("FsNotificationManager::DoHandleChange() destinationName=%S, filterName=%S"),&aDestinationNamePtrC,filter.iPath);
-                filterMatch = DoMatchFilter(aRequest,aDestinationNamePtrC,filter);
+                __PRINT2(_L("FsNotificationManager::DoHandleChange() destinationName=%S, filterName=%S"),&aNotificationInfo.NewName().FullName(),filter.iPath);
+                if(aNotificationInfo.DestDriveIsSet())
+                    filterMatch = DoMatchFilter(bufferMsg,aNotificationInfo.NewName().FullName().Mid(2),filter);
+                else
+                    filterMatch = DoMatchFilter(bufferMsg,aNotificationInfo.NewName().FullName(),filter);
                 }
 			}
 
-		if(filterMatch || (aType == TFsNotification::EMediaChange))//Match or MediaChange (report regardless of filters)
+        if(filterMatch || (aNotificationInfo.NotificationType() == TFsNotification::EMediaChange))//Match or MediaChange (report regardless of filters)
 			{
 			//Matching - Handle change
 			
@@ -1275,7 +986,7 @@
 			//So that we can do IPC from a single place.
 			CFsNotificationBlock* block = iPool->Allocate();
 				
-			TInt r = aNotifyRequest->NotifyChange(aRequest,aOperationName,aType,*block);
+            TInt r = aNotifyRequest->NotifyChange(&aNotificationInfo,*block);
 				
 			//Free block
 			iPool->Free(block);