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) |
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 |
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")); |
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; |
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) |