userlibandfileserver/fileserver/sfile/sf_notifier.cpp
changeset 299 b5a01337d018
parent 31 56f325a607ea
equal deleted inserted replaced
297:b2826f67641f 299:b5a01337d018
    22 RFastLock FsNotificationManager::iChainLock;
    22 RFastLock FsNotificationManager::iChainLock;
    23 TInt FsNotificationManager::iFilterRegister[];
    23 TInt FsNotificationManager::iFilterRegister[];
    24 CFsPool<CFsNotificationBlock>* FsNotificationManager::iPool;
    24 CFsPool<CFsNotificationBlock>* FsNotificationManager::iPool;
    25 
    25 
    26 
    26 
    27 CFsNotificationPathFilter* CFsNotificationPathFilter::NewL(const TDesC& aPath, const TDesC& aFilename)
    27 CFsNotificationPathFilter* CFsNotificationPathFilter::NewL(const TDesC& aPath, const TDesC& aFilename, TInt aDriveNum)
    28 	{
    28 	{
    29 	CFsNotificationPathFilter* self = new (ELeave) CFsNotificationPathFilter();
    29 	CFsNotificationPathFilter* self = new (ELeave) CFsNotificationPathFilter();
    30 	CleanupStack::PushL(self);
    30 	CleanupStack::PushL(self);
    31 	self->ConstructL(aPath,aFilename);
    31 	self->ConstructL(aPath,aFilename,aDriveNum);
    32 	CleanupStack::Pop(self);
    32 	CleanupStack::Pop(self);
    33 	return self;
    33 	return self;
    34 	}
    34 	}
    35 
    35 
    36 void CFsNotificationPathFilter::ConstructL(const TDesC& aPath, const TDesC& aFilename)
    36 void CFsNotificationPathFilter::ConstructL(const TDesC& aPath, const TDesC& aFilename, TInt aDriveNum)
    37 	{
    37 	{
    38 	//Allocate the path and filename
    38 	//Allocate the path and filename
    39 	iPath = aPath.AllocL();
    39 	iPath = aPath.AllocL();
    40 	iFilename = aFilename.AllocL();	
    40 	iFilename = aFilename.AllocL();	
       
    41 	iDriveNum = aDriveNum;
    41 	}
    42 	}
    42 
    43 
    43 CFsNotificationPathFilter::~CFsNotificationPathFilter()
    44 CFsNotificationPathFilter::~CFsNotificationPathFilter()
    44 	{
    45 	{
    45 	if(iFilename)
    46 	if(iFilename)
   174 			TFsNotificationTypeArray& filterList = (*currentDriveFilters)[filterType];
   175 			TFsNotificationTypeArray& filterList = (*currentDriveFilters)[filterType];
   175 			TInt filterTypeCount = filterList.Count();
   176 			TInt filterTypeCount = filterList.Count();
   176 			if(filterTypeCount)
   177 			if(filterTypeCount)
   177 				{
   178 				{
   178 				//Remove this type from the filter register
   179 				//Remove this type from the filter register
   179 				TFsNotification::TFsNotificationType type = FsNotificationHelper::NotificationType(filterType);
   180 				TFsNotification::TFsNotificationType type = CFsNotificationInfo::NotificationType(filterType);
   180 				FsNotificationManager::SetFilterRegister(type,EFalse,filterTypeCount);
   181 				FsNotificationManager::SetFilterRegister(type,EFalse,filterTypeCount);
   181 				}
   182 				}
   182 			filterList.Reset();
   183 			filterList.Reset();
   183 			filterList.Close();
   184 			filterList.Close();
   184 			}
   185 			}
   186 		currentDriveFilters->Close();
   187 		currentDriveFilters->Close();
   187 		iterator.RemoveCurrent();
   188 		iterator.RemoveCurrent();
   188 		currentDriveFilters = (TFsNotificationTypeDriveArray*)iterator.NextValue();
   189 		currentDriveFilters = (TFsNotificationTypeDriveArray*)iterator.NextValue();
   189 		}
   190 		}
   190 	iDrivesTypesFiltersMap.Close();
   191 	iDrivesTypesFiltersMap.Close();
   191 	iPathFilterList.ResetAndDestroy();
       
   192 	iPathFilterList.Close();
       
   193 	return KErrNone;
   192 	return KErrNone;
   194 	}
   193 	}
   195 
   194 
   196 TInt CFsNotifyRequest::AddFilterL(CFsNotificationPathFilter* aFilter, TUint aMask)
   195 TInt CFsNotifyRequest::AddFilterL(CFsNotificationPathFilter* aFilter, TUint aMask)
   197 	{
   196 	{
   198 	__PRINT(_L("CFsNotifyRequest::AddFilterL"));
   197 	__PRINT(_L("CFsNotifyRequest::AddFilterL"));
   199 
   198 
   200 	iPathFilterList.AppendL(aFilter);
       
   201 	
       
   202 	//Get the drive number to so know which drive array to add the filter(s) to.
   199 	//Get the drive number to so know which drive array to add the filter(s) to.
   203 	TInt driveNum = FsNotificationHelper::DriveNumber(aFilter->iPath->Des()); 
   200 	TInt driveNum = aFilter->iDriveNum; 
   204 	
   201 	
   205 	TInt notifyType = 1; 
   202 	TInt notifyType = 1; 
   206 	TInt r = KErrNone;
   203 	TInt r = KErrNone;
   207 	//Create/Add a TypeFilter for each type in aMask
   204 	//Create/Add a TypeFilter for each type in aMask
   208 	while((notifyType & KNotificationValidFiltersMask) && (aMask & KNotificationValidFiltersMask))
   205 	while((notifyType & KNotificationValidFiltersMask) && (aMask & KNotificationValidFiltersMask))
   211 		if(aMask & notifyType)
   208 		if(aMask & notifyType)
   212 			{
   209 			{
   213 			TFsNotificationTypeFilter typeFilter;
   210 			TFsNotificationTypeFilter typeFilter;
   214 			typeFilter.iNotificationType = (TFsNotification::TFsNotificationType) notifyType;
   211 			typeFilter.iNotificationType = (TFsNotification::TFsNotificationType) notifyType;
   215 			typeFilter.iPathFilter = aFilter;
   212 			typeFilter.iPathFilter = aFilter;
   216 			TInt index = FsNotificationHelper::TypeToIndex(typeFilter.iNotificationType);
   213 			TInt index = CFsNotificationInfo::TypeToIndex(typeFilter.iNotificationType);
   217 			
   214 			
   218 			//If the per-drive-filterLists have not
   215 			//If the per-drive-filterLists have not
   219 			//been set up yet then do so now.
   216 			//been set up yet then do so now.
   220 			TFsNotificationTypeDriveArray* driveArray = iDrivesTypesFiltersMap.Find(driveNum);
   217 			TFsNotificationTypeDriveArray* driveArray = iDrivesTypesFiltersMap.Find(driveNum);
   221 			if(!driveArray)
   218 			if(!driveArray)
   254 TInt CFsNotifyRequest::ClientMsgHandle()
   251 TInt CFsNotifyRequest::ClientMsgHandle()
   255 	{
   252 	{
   256 	return iClientMsg.Handle();
   253 	return iClientMsg.Handle();
   257 	}
   254 	}
   258 
   255 
       
   256 const RMessage2& CFsNotifyRequest::BufferMessage()
       
   257     {
       
   258     return iBufferMsg;
       
   259     }
       
   260 
   259 void CFsNotifyRequest::CloseNotification()
   261 void CFsNotifyRequest::CloseNotification()
   260 	{
   262 	{
   261 	__PRINT(_L("CFsNotifyRequest::CloseNotification()"));
   263 	__PRINT(_L("CFsNotifyRequest::CloseNotification()"));
   262 	iBufferMsg.Complete(KErrNone);
   264 	iBufferMsg.Complete(KErrNone);
   263 	if(ClientMsgHandle()!=0)
   265 	if(ClientMsgHandle()!=0)
   326 		if(iChainLock.Handle() == 0)
   328 		if(iChainLock.Handle() == 0)
   327 			{
   329 			{
   328 			User::LeaveIfError(iChainLock.CreateLocal());	
   330 			User::LeaveIfError(iChainLock.CreateLocal());	
   329 			}
   331 			}
   330 		iNotifyRequests = TheContainer->CreateL();
   332 		iNotifyRequests = TheContainer->CreateL();
   331 		iPool = CFsPool<CFsNotificationBlock>::New(KNotificationPoolSize);
   333 		iPool = CFsPool<CFsNotificationBlock>::New(KNotificationPoolSize,CFsNotificationBlock::New);
   332 		User::LeaveIfNull(iPool);
   334 		User::LeaveIfNull(iPool);
   333 		}
   335 		}
   334 	}
   336 	}
   335 
   337 
   336 void FsNotificationManager::SetFilterRegister(TUint aFilter, TBool aAdd, TInt aCount)
   338 void FsNotificationManager::SetFilterRegister(TUint aFilter, TBool aAdd, TInt aCount)
   337 	{
   339 	{
   338 	__PRINT2(_L("FsNotificationManager::SetFilterRegister(aFilter=%u,aAdd=%d)"),aFilter,aAdd);
   340 	__PRINT2(_L("FsNotificationManager::SetFilterRegister(aFilter=%u,aAdd=%d)"),aFilter,aAdd);
   339 	TInt index = FsNotificationHelper::TypeToIndex((TFsNotification::TFsNotificationType)aFilter);
   341 	TInt index = CFsNotificationInfo::TypeToIndex((TFsNotification::TFsNotificationType)aFilter);
   340 	TInt& fr = FsNotificationManager::FilterRegister(index);
   342 	TInt& fr = FsNotificationManager::FilterRegister(index);
   341 	__ASSERT_DEBUG((aAdd) ? fr >= 0 : fr > 0,Fault(ENotificationFault));
   343 	__ASSERT_DEBUG((aAdd) ? fr >= 0 : fr > 0,Fault(ENotificationFault));
   342 	fr+= aAdd ? aCount : -aCount; 
   344 	fr+= aAdd ? aCount : -aCount; 
   343 	}
   345 	}
   344 
   346 
   398 	__PRINT(_L("<---FsNotificationManager::Unlock()"));
   400 	__PRINT(_L("<---FsNotificationManager::Unlock()"));
   399 	iChainLock.Signal();
   401 	iChainLock.Signal();
   400 	}
   402 	}
   401 
   403 
   402 //Get the notification type based on the TFsMessage function
   404 //Get the notification type based on the TFsMessage function
   403 void FsNotificationHelper::NotificationType(TInt aFunction,TFsNotification::TFsNotificationType& aNotificationType)
   405 void CFsNotificationInfo::NotificationType(TInt aFunction,TNotificationType& aNotificationType)
   404 	{
   406 	{
   405 	__PRINT(_L("FsNotificationHelper::NotificationType"));
   407 	__PRINT(_L("CFsNotificationInfo::NotificationType"));
   406 	switch(aFunction)
   408 	switch(aFunction)
   407 		{
   409 		{
   408 		case EFsFileWrite:
   410 		case EFsFileWrite:
   409 		case EFsFileWriteDirty:
   411 		case EFsFileWriteDirty:
   410 		case EFsFileSetSize:
   412 		case EFsFileSetSize:
   484 	{
   486 	{
   485 	return (TAny*)&iData;
   487 	return (TAny*)&iData;
   486 	}
   488 	}
   487 
   489 
   488 
   490 
   489 //=====FsNotificationManager===========================
       
   490  
   491  
   491 //Get the path of the file, folder or drive name based on the TFsMessage function
       
   492 void FsNotificationHelper::PathName(CFsClientMessageRequest& aRequest, TDes& aPath)
       
   493 	{
       
   494 	__PRINT(_L("FsNotificationHelper::PathName"));
       
   495 	//Get the notification type
       
   496 	TInt function = aRequest.Operation()->Function();
       
   497 	
       
   498 	//Get the filename(s)
       
   499 	switch(function)
       
   500 		{
       
   501 		case EFsFileWrite:			//EParseSrc | EFileShare
       
   502 		case EFsFileSetSize:		//EParseSrc | EFileShare
       
   503 		case EFsFileSetAtt:			//EParseDst | EParseSrc, - should not use these; has share.
       
   504 		case EFsFileSet:
       
   505 		case EFsFileWriteDirty:		//EFileShare
       
   506 			{
       
   507 			CFileShare* share = NULL;
       
   508 			CFileCB* file = NULL;
       
   509 			GetFileFromScratch(&aRequest,share,file);	
       
   510 			aPath.Append(file->DriveNumber() + 'A');
       
   511 			aPath.Append(':');
       
   512 			aPath.Append(file->FileName().Des());
       
   513 			break;
       
   514 			}
       
   515 		case EFsFileCreate:			//EParseSrc
       
   516 		case EFsDelete:				//EParseSrc
       
   517 		case EFsSetEntry:			//EParseSrc,
       
   518 		case EFsFileRename:			//EParseDst | EParseSrc,
       
   519 		case EFsRename:				//EParseDst | EParseSrc,
       
   520 		case EFsReplace:			//EParseDst | EParseSrc,
       
   521 		case EFsFileReplace:		//EParseSrc
       
   522 			{
       
   523 			aPath.Copy(aRequest.Src().FullName());
       
   524 			break;
       
   525 			}
       
   526         case EFsRmDir:              //EParseSrc
       
   527         case EFsMkDir:              //EParseSrc
       
   528             {
       
   529             aPath.Copy(aRequest.Src().DriveAndPath());
       
   530             break;
       
   531             }
       
   532 		case EFsFormatNext:			//EParseSrc
       
   533 		case EFsDismountFileSystem: //0
       
   534 		case EFsMountFileSystem:	//0
       
   535 		case EFsSetVolume:			//0
       
   536 		case EFsSetDriveName:		//ESync
       
   537 		case EFsRawDiskWrite:		//EParseSrc
       
   538 		case EFsMountFileSystemScan:
       
   539 			{
       
   540 			_LIT(KFormatDrive,"?:");
       
   541 			TBuf<2> drive;
       
   542 			drive.Append(KFormatDrive);
       
   543 			drive[0] = TText(aRequest.Drive()->DriveNumber() + 'A');
       
   544 			aPath.Copy(drive);
       
   545 			break;
       
   546 			}
       
   547 		default:
       
   548 			ASSERT(0);
       
   549 			break;
       
   550 		}
       
   551 	}
       
   552 
       
   553 //Get the new path of the file, folder or drive name based on the TFsMessage function
       
   554 void FsNotificationHelper::NewPathName(CFsClientMessageRequest& aRequest, TPtrC& aNewPath)
       
   555 	{
       
   556 	__PRINT(_L("FsNotificationHelper::NewPathName"));
       
   557 	//Get the notification type
       
   558 	TInt function = aRequest.Operation()->Function();
       
   559 
       
   560 	//Get the filename(s)
       
   561 	switch(function)
       
   562 		{
       
   563 		case EFsFileRename:			//EParseDst | EParseSrc,
       
   564 		case EFsRename:				//EParseDst | EParseSrc,
       
   565 		case EFsReplace:			//EParseDst | EParseSrc,
       
   566 			{
       
   567 			aNewPath.Set(aRequest.Dest().FullName());
       
   568 			break;
       
   569 			}
       
   570 		case EFsSetDriveName:		//ESync
       
   571 			{
       
   572 			TFileName name;
       
   573 			aRequest.ReadL(KMsgPtr1, name);
       
   574 			aNewPath.Set(name);
       
   575 			break;
       
   576 			}
       
   577 		case EFsSetVolume:			//0
       
   578 			{
       
   579 			TFileName name;
       
   580 			aRequest.ReadL(KMsgPtr0, name);
       
   581 			aNewPath.Set(name);
       
   582 			break;
       
   583 			}
       
   584 		default:
       
   585 			{
       
   586 			ASSERT(0);
       
   587 			break;
       
   588 			}
       
   589 		}
       
   590 	}
       
   591 
       
   592 //Get the size of the notification based on its type
       
   593 TInt FsNotificationHelper::NotificationSize(CFsClientMessageRequest& aRequest, TFsNotification::TFsNotificationType aNotificationType, const TDesC& aName)
       
   594 	{
       
   595 	__PRINT(_L("FsNotificationHelper::NotificationSize"));
       
   596 	
       
   597 	/*
       
   598 	 * If there are no new names, the order of the data in the buffer is:
       
   599 	 * Word1   : NotificationSize (2 bytes) , PathSize (2 bytes)
       
   600 	 * Word2   : NotificationType (Lower 2 bytes)
       
   601 	 * Word(s) : Path (TText8) , [Any sub-class members]
       
   602 	 * 
       
   603 	 * Else for notification types ERename, EVolumeName and EDriveName the order is:
       
   604 	 * Word1   : NotificationSize (2 bytes) , PathSize (2 bytes)
       
   605 	 * Word2   : NewNameSize (2 bytes) , NotificationType (2 bytes)
       
   606 	 * Word(s) : Path (TText8) , NewName (TText8)
       
   607 	 * 
       
   608 	 * EOverflow size: KNotificationHeaderSize
       
   609 	 */	
       
   610 	
       
   611 	TInt size = KNotificationHeaderSize + Align4(aName.Size());
       
   612 	
       
   613 	switch(aNotificationType)
       
   614 		{
       
   615 		//NewName
       
   616  		case TFsNotification::ERename:
       
   617 		case TFsNotification::EVolumeName:
       
   618 		case TFsNotification::EDriveName:
       
   619 			{
       
   620 			TPtrC dest;
       
   621 			NewPathName(aRequest,dest);
       
   622 			size += Align4(dest.Size()); 
       
   623 			break;
       
   624 			}
       
   625 		case TFsNotification::EFileChange:
       
   626 			{
       
   627 			size += sizeof(TInt64);
       
   628 			break;
       
   629 			}
       
   630 		case TFsNotification::EAttribute:
       
   631 			{
       
   632 			size += sizeof(TUint64);
       
   633 			break;
       
   634 			}
       
   635 		case TFsNotification::ECreate: 
       
   636 		case TFsNotification::EDelete:
       
   637 		case TFsNotification::EMediaChange:
       
   638 			{
       
   639 			break;
       
   640 			}
       
   641 		default:
       
   642 			{
       
   643 			ASSERT(0);
       
   644 			break;
       
   645 			}
       
   646 		}
       
   647 	return (TUint16) size;
       
   648 	}
       
   649 
       
   650 TFsNotification::TFsNotificationType FsNotificationHelper::NotificationType(TInt& aIndex)
       
   651 	{
       
   652 	__PRINT(_L("FsNotificationHelper::NotificationType(TInt)"));
       
   653 	__ASSERT_DEBUG(aIndex < KNumRegisterableFilters, Fault(ENotificationFault));
       
   654 	
       
   655 	switch(aIndex) //No break statements here on purpose
       
   656 		{
       
   657 		case 7 : return TFsNotification::EMediaChange;
       
   658 		case 6 : return TFsNotification::EDriveName;
       
   659 		case 5 : return TFsNotification::EVolumeName;
       
   660 		case 4 : return TFsNotification::EDelete;
       
   661 		case 3 : return TFsNotification::EAttribute;
       
   662 		case 2 : return TFsNotification::ECreate;
       
   663 		case 1 : return TFsNotification::ERename;
       
   664 		case 0 : return TFsNotification::EFileChange;
       
   665 		default: ASSERT(0); return (TFsNotification::TFsNotificationType) 0;
       
   666 		}
       
   667 	}
       
   668 
       
   669 //Get the array index of the notification based on its type
       
   670 TInt FsNotificationHelper::TypeToIndex(TFsNotification::TFsNotificationType aType)
       
   671 	{
       
   672 	__PRINT(_L("FsNotificationHelper::ArrayIndex"));
       
   673 
       
   674 	TInt index = 0; 
       
   675 	switch(aType) //No break statements here on purpose
       
   676 		{
       
   677 		case TFsNotification::EMediaChange: index++;
       
   678 		case TFsNotification::EDriveName:	index++;
       
   679 		case TFsNotification::EVolumeName:	index++;
       
   680 		case TFsNotification::EDelete:	 	index++;
       
   681 		case TFsNotification::EAttribute:	index++;
       
   682 		case TFsNotification::ECreate:	 	index++;
       
   683 		case TFsNotification::ERename:	 	index++;
       
   684 		case TFsNotification::EFileChange:	// skip;
       
   685 		default: break;
       
   686 		}
       
   687 	__ASSERT_DEBUG(index < KNumRegisterableFilters, Fault(ENotificationFault));
       
   688 	return index;
       
   689 	}
       
   690 
       
   691 TInt FsNotificationHelper::DriveNumber(const TPtrC& aPath)
       
   692 	{
       
   693 	if(aPath.Length() >= 2 && ((TChar)aPath[1])==(TChar)':')
       
   694 		{
       
   695 		TChar driveChar = ((TChar)aPath[0]);
       
   696 		driveChar.UpperCase();
       
   697 		TInt driveNum = driveChar-(TChar)'A'; 
       
   698 		return driveNum;
       
   699 		}
       
   700 	else
       
   701 		{
       
   702 		return KErrNotFound;
       
   703 		}
       
   704 	}
       
   705 
       
   706 //Get the attributes set and cleared
       
   707 void FsNotificationHelper::Attributes(CFsClientMessageRequest& aRequest, TUint& aSet, TUint& aClear)
       
   708 	{
       
   709 	__PRINT(_L("FsNotificationHelper::Attributes"));
       
   710 
       
   711 	TInt function = aRequest.Operation()->Function();
       
   712 	const RMessage2& msg = aRequest.Message();
       
   713 
       
   714 	switch(function)
       
   715 		{
       
   716 		case EFsFileSet:
       
   717 			{
       
   718 			aSet = msg.Int1();
       
   719 			aClear = msg.Int2();
       
   720 			break;
       
   721 			}
       
   722 		case EFsFileSetAtt:
       
   723 			{
       
   724 			aSet = msg.Int0();
       
   725 			aClear = msg.Int1();
       
   726 			break;
       
   727 			}
       
   728 		case EFsSetEntry:
       
   729 			{
       
   730 			aSet = msg.Int2();
       
   731 			aClear = msg.Int3();
       
   732 			break;
       
   733 			}
       
   734 		default:
       
   735 			{
       
   736 			ASSERT(0);
       
   737 			break;
       
   738 			}
       
   739 		}
       
   740 	}
       
   741 
   492 
   742 
   493 
   743 TBool CFsNotifyRequest::ValidateNotification(TInt aNotificationSize, TInt& aServerTail)
   494 TBool CFsNotifyRequest::ValidateNotification(TInt aNotificationSize, TInt& aServerTail)
   744 	{
   495 	{
   745 	__PRINT(_L("CFsNotifyRequest::ValidateNotification"));
   496 	__PRINT(_L("CFsNotifyRequest::ValidateNotification"));
   896 // Called from FsNotificationManager::HandleChange().
   647 // Called from FsNotificationManager::HandleChange().
   897 // Sends notifications into the client's buffer.
   648 // Sends notifications into the client's buffer.
   898 // If there is a iClientMsg then this is the first time this
   649 // If there is a iClientMsg then this is the first time this
   899 // has been called since the client called RequestNotifications.
   650 // has been called since the client called RequestNotifications.
   900 // In this situation we complete the client request.
   651 // In this situation we complete the client request.
   901 TInt CFsNotifyRequest::NotifyChange(CFsClientMessageRequest* aRequest,const TDesC& aName, TFsNotification::TFsNotificationType aNotificationType, CFsNotificationBlock& aBlock)
   652 TInt CFsNotifyRequest::NotifyChange(CFsNotificationInfo* aRequest, CFsNotificationBlock& aBlock)
   902 	{
   653 	{
   903 	/*
   654 	/*
   904 	 * Different notification types have different data associated with them.
   655 	 * Different notification types have different data associated with them.
   905 	 * 
   656 	 * 
   906 	 * All types EXCEPT for ERename, EVolumeName and EDriveName have the following data 
   657 	 * All types EXCEPT for ERename, EVolumeName and EDriveName have the following data 
   918 	 * and there will be no Word3.
   669 	 * and there will be no Word3.
   919 	 */	
   670 	 */	
   920 	
   671 	
   921 	__PRINT(_L("CFsNotifyRequest::NotifyChange()"));
   672 	__PRINT(_L("CFsNotifyRequest::NotifyChange()"));
   922 
   673 
   923 	TInt notificationSize = FsNotificationHelper::NotificationSize(*aRequest,aNotificationType,aName);
   674     TInt notificationSize = CFsNotificationInfo::NotificationSize(*aRequest);
   924 	
   675     
   925 	iClientSyncLock.Wait();
   676 	iClientSyncLock.Wait();
   926 	iTailSemaphore.Wait();
   677 	iTailSemaphore.Wait();
   927 	
   678 	
   928 	TInt tail = iServerTail;
   679 	TInt tail = iServerTail;
   929 	
   680 	
   934 	//the standard attributes that all notifications have.
   685 	//the standard attributes that all notifications have.
   935 
   686 
   936 	//We can store the size of the notification 
   687 	//We can store the size of the notification 
   937 	//and the size of the name in the same word.
   688 	//and the size of the name in the same word.
   938 	
   689 	
       
   690 	TBuf<2> driveBuf;
       
   691 	driveBuf.SetLength(2);
       
   692     TChar driveLetter = 'A';
       
   693     RFs::DriveToChar(aRequest->DriveNumber(),driveLetter);
       
   694     driveBuf[0] = (TText)driveLetter;
       
   695     driveBuf[1] = (TText)':';
       
   696 	
   939 	TUint16 nameLen = 0;	//Overflow has no name
   697 	TUint16 nameLen = 0;	//Overflow has no name
   940 	TInt notifSize = KNotificationHeaderSize;
   698 	TInt notifSize = KNotificationHeaderSize;
   941 	if(!overflow)
   699 	if(!overflow)
   942 		{
   700 		{
   943 		nameLen = (TUint16)aName.Size();
   701         nameLen = (TUint16)aRequest->SourceSize();
   944 		notifSize = notificationSize;
   702 		notifSize = notificationSize;
   945 		}
   703 		}
   946 	else 
   704 	else 
   947 		{
   705 		{
   948 		aNotificationType = TFsNotification::EOverflow;
   706         aRequest->NotificationType() = TFsNotification::EOverflow;
   949 		}	
   707 		}	
   950 
   708 
   951 	iServerTail = tail + notifSize;
   709 	iServerTail = tail + notifSize;
   952 	iTailSemaphore.Signal();
   710 	iTailSemaphore.Signal();
   953 	
   711 	
   956 	//Store notification Size and NameSize (Word1)
   714 	//Store notification Size and NameSize (Word1)
   957 	TUint sizeNameLen = (notifSize << 16) | nameLen;	
   715 	TUint sizeNameLen = (notifSize << 16) | nameLen;	
   958 	memcpy((TText8*)aBlock.Data()+writeOffset,&sizeNameLen,sizeof(TUint));
   716 	memcpy((TText8*)aBlock.Data()+writeOffset,&sizeNameLen,sizeof(TUint));
   959 	writeOffset+=sizeof(TUint);
   717 	writeOffset+=sizeof(TUint);
   960 
   718 
   961 	TPtrC newName;
   719     if (aRequest->NotificationType() == TFsNotification::ERename ||
   962 	
   720         aRequest->NotificationType() == TFsNotification::EVolumeName ||
   963 	if (aNotificationType == TFsNotification::ERename ||
   721         aRequest->NotificationType() == TFsNotification::EDriveName)
   964 		aNotificationType == TFsNotification::EVolumeName ||
   722         {
   965 		aNotificationType == TFsNotification::EDriveName)
   723         //Store NewNameSize and notification Type (Word2)
   966 		{
   724         TUint typeNewNameLen = ((TUint16)aRequest->NewNameSize() << 16) | (TUint16)aRequest->NotificationType();
   967 		FsNotificationHelper::NewPathName(*aRequest,newName);
       
   968 		//Store NewNameSize and notification Type (Word2)
       
   969 		TUint typeNewNameLen = ((TUint16)newName.Size() << 16) | (TUint16)aNotificationType;
       
   970 		memcpy((TText8*)aBlock.Data()+writeOffset,&typeNewNameLen,sizeof(TUint));
   725 		memcpy((TText8*)aBlock.Data()+writeOffset,&typeNewNameLen,sizeof(TUint));
   971 		}
   726 		}
   972 	else
   727 	else
   973 		{
   728 		{
   974 		//Store notification Type (Word2)
   729 		//Store notification Type (Word2)
   975 		memcpy((TText8*)aBlock.Data()+writeOffset,&aNotificationType,sizeof(TUint));
   730         memcpy((TText8*)aBlock.Data()+writeOffset,&aRequest->NotificationType(),sizeof(TUint));
   976 		}
   731 		}
   977 	writeOffset+=sizeof(TUint);
   732 	writeOffset+=sizeof(TUint);
   978 	
   733 	
   979 	CFileShare* share = NULL;
       
   980     CFileCB* file = NULL;
       
   981     if(aRequest) //Don't always have a request such as when called from localdrives.
       
   982         {
       
   983         GetFileFromScratch(aRequest, share, file);
       
   984         }
       
   985     
       
   986     //
   734     //
   987     //Store UID
   735     //Store UID
   988     /*
   736 	memcpy((TText8*)aBlock.Data()+writeOffset,&aRequest->Uid().iUid,sizeof(TUint32));
   989 	TUid uid;
   737 	writeOffset+=sizeof(TUint32);
   990 	uid.iUid = KErrUnknown;
   738 	
   991 	if(aRequest && aRequest->Operation()->iFunction == EFsFileWriteDirty)
   739 	
       
   740 	if(!overflow)
       
   741 		{
       
   742 		//Store Name (Word3)
   992 	    {
   743 	    {
   993 	    uid = aRequest->iUID;
   744 	    //Store driveColon
       
   745 	    if(aRequest->NotificationType()!=TFsNotification::EMediaChange)
       
   746 	        {
       
   747 	        memcpy((TText8*)aBlock.Data()+writeOffset,driveBuf.Ptr(),driveBuf.Size());
       
   748 	        writeOffset += driveBuf.Size(); //NB: Not Align4'd deliberately.
       
   749 	        }
       
   750 	    memcpy((TText8*)aBlock.Data()+writeOffset,aRequest->Source().FullName().Ptr(),aRequest->Source().FullName().Size());
       
   751 	    writeOffset += Align4(aRequest->Source().FullName().Size());
   994 	    }
   752 	    }
   995 	else if(aRequest)
   753 
   996 	    {
   754         switch (aRequest->NotificationType())
   997 	    uid = aRequest->Message().Identity();
       
   998 	    }
       
   999 	memcpy((TText8*)aBlock.Data()+writeOffset,&uid.iUid,sizeof(TUint32));
       
  1000 	writeOffset+=sizeof(TUint32);
       
  1001 	*/
       
  1002 	
       
  1003 	if(!overflow)
       
  1004 		{
       
  1005 		//Store Name (Word3)
       
  1006 		memcpy((TText8*)aBlock.Data()+writeOffset,aName.Ptr(),aName.Size());
       
  1007 		writeOffset += Align4(aName.Size());
       
  1008 		
       
  1009 
       
  1010 		switch (aNotificationType)
       
  1011 			{
   755 			{
  1012 			case TFsNotification::EFileChange:
   756 			case TFsNotification::EFileChange:
       
   757 			case TFsNotification::EAttribute:
  1013 				{
   758 				{
  1014 				TInt64 size = 0;
   759                 memcpy((TText8*)aBlock.Data()+writeOffset,aRequest->Data(),sizeof(TInt64));
  1015 				size = file->CachedSize64();
       
  1016 				memcpy((TText8*)aBlock.Data()+writeOffset,&size,sizeof(TInt64));
       
  1017 				writeOffset += sizeof(TInt64);
   760 				writeOffset += sizeof(TInt64);
  1018 				break;
   761 				break;
  1019 				}
   762 				}
  1020 			case TFsNotification::ERename:
   763 			case TFsNotification::ERename:
  1021 			case TFsNotification::EVolumeName:
   764 			case TFsNotification::EVolumeName:
  1022 			case TFsNotification::EDriveName:
   765 			case TFsNotification::EDriveName:
  1023 				{
   766 				{
  1024 				//Store NewName
   767 				//Store NewName
  1025 				memcpy((TText8*)aBlock.Data()+writeOffset,newName.Ptr(),newName.Size());
   768 				
  1026 				writeOffset += Align4(newName.Size());
   769 				if(!aRequest->DestDriveIsSet())
       
   770 				    {
       
   771 				    //This means that the notification has come from a Mount rather than from FileServer
       
   772 				    //It also means that the new name will have the same drive letter as the source.
       
   773 				    memcpy((TText8*)aBlock.Data()+writeOffset,driveBuf.Ptr(),driveBuf.Size());
       
   774 				    writeOffset += driveBuf.Size(); //NB: Not Align4'd deliberately.
       
   775 				    }
       
   776                 memcpy((TText8*)aBlock.Data()+writeOffset,aRequest->NewName().FullName().Ptr(),aRequest->NewName().FullName().Size());
       
   777                 writeOffset += Align4(aRequest->NewName().FullName().Size());
  1027 				break;
   778 				break;
  1028 				}
   779 				}
  1029 			case TFsNotification::EAttribute:
   780 
  1030 				{
       
  1031 				TUint set=0;
       
  1032 				TUint clear=0;
       
  1033 				FsNotificationHelper::Attributes(*aRequest,set,clear);
       
  1034 				TUint64 att = MAKE_TUINT64(set,clear);
       
  1035 				memcpy((TText8*)aBlock.Data()+writeOffset,&att,sizeof(TUint64));
       
  1036 				writeOffset += sizeof(TUint64);
       
  1037 				break;
       
  1038 				}
       
  1039 			default:
   781 			default:
  1040 				{
   782 				{
  1041 				break;
   783 				break;
  1042 				}
   784 				}
  1043 			}
   785 			}
  1083 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
   825 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
  1084 
   826 
  1085 //A change has occurred in f32 represented by this
   827 //A change has occurred in f32 represented by this
  1086 //request object. Work out which CfsNotify’s are interested
   828 //request object. Work out which CfsNotify’s are interested
  1087 // (if any) and call CfsNotifyRequest::NotifyChange.
   829 // (if any) and call CfsNotifyRequest::NotifyChange.
  1088 void FsNotificationManager::HandleChange(CFsClientMessageRequest* aRequest,const TDesC& aOperationName, TFsNotification::TFsNotificationType aType)
   830 void FsNotificationManager::HandleChange(CFsNotificationInfo& aRequest)
  1089 	{
   831     {
  1090 	__PRINT2(_L("FsNotificationManager::HandleChange() aRequest=0x%x, aType=%d"),&aRequest,aType);
   832     __PRINT2(_L("FsNotificationManager::HandleChange() aNotificationInfo=0x%x,NotificationType=%d"),&aRequest,aRequest.NotificationType());
  1091 
   833     if(Count())
  1092 	Lock(); //ToDo: Read Lock (Read/Write Lock)	
   834         {
  1093 	if(Count())
   835         Lock(); //ToDo: Read Lock (Read/Write Lock) 
  1094 		{
   836         if(Count())
  1095 		//Only search while there are filters of this type set up.
   837             {
  1096 		TInt index = FsNotificationHelper::TypeToIndex(aType);
   838             //Only search while there are filters of this type set up.
  1097 		TInt& filterCount = FsNotificationManager::FilterRegister(index);
   839             TInt index = CFsNotificationInfo::TypeToIndex(aRequest.NotificationType());
  1098 		TInt seenFilter = filterCount; //Number of requests set up for this type
   840             TInt& filterCount = FsNotificationManager::FilterRegister(index);
  1099 		
   841             TInt seenFilter = filterCount; //Number of requests set up for this type
  1100 		//Iterate CFsNotifyRequests
   842             
  1101 		TInt count = iNotifyRequests->Count();
   843             //Iterate CFsNotifyRequests
  1102 		
   844             TInt count = iNotifyRequests->Count();
  1103 		if(aType == TFsNotification::EMediaChange)
   845             
  1104 			seenFilter = count;
   846             if(aRequest.NotificationType() == TFsNotification::EMediaChange)
  1105 		
   847                 seenFilter = count;
  1106 		//If there aren't any requests then breakout
   848             
  1107 		if(count == 0)
   849             //If there aren't any requests then breakout
  1108 			{
   850             if(count == 0)
  1109 			Unlock();
   851                 {
  1110 			return;
   852                 Unlock();
  1111 			}
   853                 return;
  1112 		
   854                 }
  1113 		TInt driveNum = FsNotificationHelper::DriveNumber(aOperationName); 
   855             
  1114 
   856             //For every notification request(i.e. every CFsNotify client-side).
  1115 		//For every notification request.
   857             for(TInt i=0; i<count && seenFilter; ++i)
  1116 		for(TInt i=0; i<count && seenFilter; ++i)
   858                 {
  1117 			{
   859                 CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)(*iNotifyRequests)[i];
  1118 			CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)(*iNotifyRequests)[i];
   860                 CFsNotifyRequest::TNotifyRequestStatus status = notifyRequest->ActiveStatus();
  1119 			CFsNotifyRequest::TNotifyRequestStatus status = notifyRequest->ActiveStatus();
   861                 if(! (status==CFsNotifyRequest::EActive || 
  1120 			if(! (status==CFsNotifyRequest::EActive || 
   862                       status==CFsNotifyRequest::EOutstanding))
  1121 				  status==CFsNotifyRequest::EOutstanding))
   863                     {
  1122 				{
   864                     //Not active; check next notification request
  1123 				//Not active; check next notification request
   865                     continue;
  1124 				continue;
   866                     }
  1125 				}
   867                 
  1126 			
   868                 //Check whether we are interested in this change.
  1127 			//Check whether we are interested in this change.
   869                 //Get the filters associated with this operation on this drive
  1128 			//Get the filters associated with this operation on this drive
   870                 TFsNotificationTypeArray* filterList = notifyRequest->FilterTypeList(aRequest.DriveNumber(),index);
  1129 			TFsNotificationTypeArray* filterList = notifyRequest->FilterTypeList(driveNum,index);
   871                 DoHandleChange(filterList,seenFilter,aRequest,notifyRequest);
  1130 			DoHandleChange(filterList,seenFilter,aRequest,notifyRequest,aOperationName,aType);
   872 
  1131 
   873                 if(aRequest.NotificationType()==TFsNotification::EMediaChange)
  1132 			if(aType==TFsNotification::EMediaChange)
   874                     continue; //next request
  1133 				continue; //next request
   875                 
  1134 			
   876                 //If there are still filters to check
  1135 			//If there are still filters to check
   877                 if(seenFilter)
  1136 			if(seenFilter)
   878                     {
  1137 				{
   879                     //Check changes that are not tied to a particular drive
  1138 				//Check changes that are not tied to a particular drive
   880                     filterList = notifyRequest->FilterTypeList(KErrNotFound,index);
  1139 				filterList = notifyRequest->FilterTypeList(KErrNotFound,index);
   881                     DoHandleChange(filterList,seenFilter,aRequest,notifyRequest);
  1140 				DoHandleChange(filterList,seenFilter,aRequest,notifyRequest,aOperationName,aType);
   882                     }
  1141 				}
   883                 }
  1142 			}
   884             }
  1143 		}
   885         Unlock();
  1144 	Unlock();
   886         }
  1145 	}
   887     }
  1146 
       
  1147 //A change has occurred in f32 represented by this
       
  1148 //request object. Work out which CfsNotify’s are interested
       
  1149 // (if any) and call CfsNotifyRequest::NotifyChange.
       
  1150 void FsNotificationManager::HandleChange(CFsClientMessageRequest& aRequest, TFsNotification::TFsNotificationType aType)
       
  1151 	{
       
  1152 	__PRINT(_L("FsNotificationManager::HandleChange"));
       
  1153 	TFileName currentOperationsName;
       
  1154 	FsNotificationHelper::PathName(aRequest, currentOperationsName);
       
  1155 	if(currentOperationsName.Length())
       
  1156 		HandleChange(&aRequest,currentOperationsName,aType);
       
  1157 	}
       
  1158 
       
  1159 //A change has occurred in f32 represented by this
       
  1160 //request object. Work out which CfsNotify’s are interested
       
  1161 // (if any) and call CfsNotifyRequest::NotifyChange.
       
  1162 void FsNotificationManager::HandleChange(CFsClientMessageRequest& aRequest)
       
  1163 	{
       
  1164 	if(Count() && aRequest.Message().Handle() != KLocalMessageHandle)
       
  1165 		{
       
  1166 		__PRINT(_L("FsNotificationManager::HandleChange"));
       
  1167 		TFsNotification::TFsNotificationType operationNotificationType;
       
  1168 		FsNotificationHelper::NotificationType(aRequest.FsFunction(), operationNotificationType);
       
  1169 		HandleChange(aRequest,operationNotificationType);
       
  1170 		}
       
  1171 	}
       
  1172 
   888 
  1173 
   889 
  1174 ////
   890 ////
  1175 #else
   891 #else
  1176 ////
   892 ////
  1177 
   893 
  1178 void FsNotificationManager::HandleChange(CFsClientMessageRequest* ,const TDesC&, TFsNotification::TFsNotificationType)
   894 void FsNotificationManager::HandleChange(CFsNotificationInfo&)
  1179 	{
   895 	{
  1180 	return;
   896 	return;
  1181 	}
   897 	}
  1182 
   898 
  1183 void FsNotificationManager::HandleChange(CFsClientMessageRequest& , TFsNotification::TFsNotificationType)
       
  1184 	{
       
  1185 	return;
       
  1186 	}
       
  1187 
       
  1188 void FsNotificationManager::HandleChange(CFsClientMessageRequest&)
       
  1189 	{
       
  1190 	return;
       
  1191 	}
       
  1192 
       
  1193 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
   899 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
  1194 
   900 
  1195 //Called from FsNotificationManager::DoHandleChange
   901 //Called from FsNotificationManager::DoHandleChange
  1196 FsNotificationManager::TFsNotificationFilterMatch FsNotificationManager::DoMatchFilter(CFsClientMessageRequest* aRequest, const TDesC& aOperationName,CFsNotificationPathFilter& aFilter)
   902 FsNotificationManager::TFsNotificationFilterMatch FsNotificationManager::DoMatchFilter(const RMessage2& aMessage, const TDesC& aOperationName,CFsNotificationPathFilter& aFilter)
  1197     {
   903     {
  1198     TFsNotificationFilterMatch filterMatch = EDifferent;
   904     TFsNotificationFilterMatch filterMatch = EDifferent;
  1199     TParsePtrC parseOp(aOperationName);
   905     TParsePtrC parseOp(aOperationName);
       
   906     
  1200     TPtrC pathOpDes = parseOp.DriveAndPath();
   907     TPtrC pathOpDes = parseOp.DriveAndPath();
  1201     TPtrC nameOpDes = parseOp.NameAndExt();
   908     TPtrC nameOpDes = parseOp.NameAndExt();
  1202     TInt pathLength = aFilter.iPath->Des().Length();
   909     TInt pathLength = aFilter.iPath->Des().Length();
  1203     TInt nameLength = aFilter.iFilename->Des().Length();
   910     TInt nameLength = aFilter.iFilename->Des().Length();
  1204     TInt paths = -1;
   911     TInt paths = -1;
  1208         paths = pathOpDes.MatchF(aFilter.iPath->Des());
   915         paths = pathOpDes.MatchF(aFilter.iPath->Des());
  1209         }
   916         }
  1210     else //if no path filter was set up
   917     else //if no path filter was set up
  1211         // then we need to ensure we don't notify on data-caged areas which we shouldn't
   918         // then we need to ensure we don't notify on data-caged areas which we shouldn't
  1212         {
   919         {
  1213         TInt r = PathCheck(aRequest,aOperationName.Mid(2),&KCapFsSysFileTemp,&KCapFsPriFileTemp,&KCapFsROFileTemp, __PLATSEC_DIAGNOSTIC_STRING("FsNotificationManager::DoHandleChange"));
   920         TInt r = PathCheck(aMessage,aOperationName.Mid(2),&KCapFsSysFileTemp,&KCapFsPriFileTemp,&KCapFsROFileTemp, __PLATSEC_DIAGNOSTIC_STRING("FsNotificationManager::DoHandleChange"));
  1214         if(r != KErrNone)
   921         if(r != KErrNone)
  1215             return EContinue; //next filter
   922             return EContinue; //next filter
  1216         }
   923         }
  1217     
   924     
  1218     if(nameLength != 0)
   925     if(nameLength != 0)
  1226          filterMatch = EMatch;
   933          filterMatch = EMatch;
  1227         }
   934         }
  1228     return filterMatch;
   935     return filterMatch;
  1229     }
   936     }
  1230 
   937 
  1231 // This is called on a per drive basis.
   938 // The aFilterTypeArray is an array for the filters that target the current drive (only).
  1232 void FsNotificationManager::DoHandleChange(TFsNotificationTypeArray* aFilterTypeArray,TInt& aSeenFilter, CFsClientMessageRequest* aRequest, CFsNotifyRequest* aNotifyRequest, const TDesC& aOperationName, TFsNotification::TFsNotificationType& aType)
   939 // This is called on a per client (CFsNotify) basis.
       
   940 void FsNotificationManager::DoHandleChange(TFsNotificationTypeArray* aFilterTypeArray,TInt& aSeenFilter, CFsNotificationInfo& aNotificationInfo, CFsNotifyRequest* aNotifyRequest)
  1233 	{		
   941 	{		
  1234 	__PRINT(_L("FsNotificationManager::DoHandleChange()"));
   942 	__PRINT(_L("FsNotificationManager::DoHandleChange()"));
  1235 	
   943 	
  1236 	if(!aFilterTypeArray)
   944 	if(!aFilterTypeArray)
  1237 		return;
   945 		return;
  1238 	
   946 	
  1239 	TInt numFilters = aFilterTypeArray->Count();
   947 	TInt numFilters = aFilterTypeArray->Count();
  1240 	
   948 	
  1241 	if(aType == TFsNotification::EMediaChange)
   949     if(aNotificationInfo.NotificationType() == TFsNotification::EMediaChange)
  1242 		numFilters = 1; //Only need to notify once per drive.
   950         numFilters = 1; //Only need to notify once per client for EMediaChange.
  1243 		
   951         
  1244 	//For every filter in this request
   952     //For every filter in this request (CFsNotify)
  1245 	for(TInt j = 0; j < numFilters;++j)
   953 	for(TInt j = 0; j < numFilters;++j)
  1246 		{
   954 		{
  1247 		//Is the correct notification type
   955 		//Is the correct notification type
  1248 		aSeenFilter--;
   956 		aSeenFilter--;
  1249 		
   957 		
  1250 		TBool filterMatch = EDifferent;
   958 		TBool filterMatch = EDifferent;
  1251 		if(aType != TFsNotification::EMediaChange)
   959         if(aNotificationInfo.NotificationType()  != TFsNotification::EMediaChange)
  1252 			{
   960 			{
  1253 			CFsNotificationPathFilter& filter = *(((*aFilterTypeArray)[j]).iPathFilter);
   961 			CFsNotificationPathFilter& filter = *(((*aFilterTypeArray)[j]).iPathFilter);
  1254 			__PRINT2(_L("FsNotificationManager::DoHandleChange() operationName=%S, filterName=%S"),&aOperationName,filter.iPath);
   962             __PRINT2(_L("FsNotificationManager::DoHandleChange() operationName=%S, filterName=%S"),&aNotificationInfo.Source().FullName(),filter.iPath);
  1255 			
   963             
  1256 			filterMatch = DoMatchFilter(aRequest,aOperationName,filter);
   964 			//buferMsg here is the message of the client *recieving* the notification
       
   965             const RMessage2& bufferMsg = aNotifyRequest->BufferMessage();
       
   966             filterMatch = DoMatchFilter(bufferMsg,aNotificationInfo.Source().FullName(),filter);
  1257 			if(filterMatch == FsNotificationManager::EContinue)
   967 			if(filterMatch == FsNotificationManager::EContinue)
  1258 			    continue; //triggers for data cages
   968 			    continue; //triggers for data cages
  1259 			
   969 			
  1260 			//We need to check for changes coming in to a directory when its rename
   970 			//We need to check for changes coming in to a directory when its rename
  1261 			if(aType == TFsNotification::ERename && filterMatch==FsNotificationManager::EDifferent)  
   971             if(aNotificationInfo.NotificationType() == TFsNotification::ERename && filterMatch==FsNotificationManager::EDifferent)  
  1262                 {
   972                 {
  1263                 TPtrC aDestinationNamePtrC;
   973                 __PRINT2(_L("FsNotificationManager::DoHandleChange() destinationName=%S, filterName=%S"),&aNotificationInfo.NewName().FullName(),filter.iPath);
  1264                 FsNotificationHelper::NewPathName(*aRequest,aDestinationNamePtrC);
   974                 if(aNotificationInfo.DestDriveIsSet())
  1265                 __PRINT2(_L("FsNotificationManager::DoHandleChange() destinationName=%S, filterName=%S"),&aDestinationNamePtrC,filter.iPath);
   975                     filterMatch = DoMatchFilter(bufferMsg,aNotificationInfo.NewName().FullName().Mid(2),filter);
  1266                 filterMatch = DoMatchFilter(aRequest,aDestinationNamePtrC,filter);
   976                 else
       
   977                     filterMatch = DoMatchFilter(bufferMsg,aNotificationInfo.NewName().FullName(),filter);
  1267                 }
   978                 }
  1268 			}
   979 			}
  1269 
   980 
  1270 		if(filterMatch || (aType == TFsNotification::EMediaChange))//Match or MediaChange (report regardless of filters)
   981         if(filterMatch || (aNotificationInfo.NotificationType() == TFsNotification::EMediaChange))//Match or MediaChange (report regardless of filters)
  1271 			{
   982 			{
  1272 			//Matching - Handle change
   983 			//Matching - Handle change
  1273 			
   984 			
  1274 			//Get a CFsNotificationBlock to use 
   985 			//Get a CFsNotificationBlock to use 
  1275 			//So that we can do IPC from a single place.
   986 			//So that we can do IPC from a single place.
  1276 			CFsNotificationBlock* block = iPool->Allocate();
   987 			CFsNotificationBlock* block = iPool->Allocate();
  1277 				
   988 				
  1278 			TInt r = aNotifyRequest->NotifyChange(aRequest,aOperationName,aType,*block);
   989             TInt r = aNotifyRequest->NotifyChange(&aNotificationInfo,*block);
  1279 				
   990 				
  1280 			//Free block
   991 			//Free block
  1281 			iPool->Free(block);
   992 			iPool->Free(block);
  1282 				
   993 				
  1283 			if(r != KErrNone)
   994 			if(r != KErrNone)