@@ -797,6 +797,8 @@ VOID DokanCompleteSetInformation(__in PREQUEST_CONTEXT RequestContext,
797797 __in PEVENT_INFORMATION EventInfo ) {
798798 PDokanCCB ccb ;
799799 PDokanFCB fcb = NULL ;
800+ BOOLEAN fcbLocked = TRUE;
801+ UNICODE_STRING oldFileName ;
800802 FILE_INFORMATION_CLASS infoClass ;
801803
802804 RequestContext -> Irp -> IoStatus .Information = EventInfo -> BufferLength ;
@@ -805,6 +807,9 @@ VOID DokanCompleteSetInformation(__in PREQUEST_CONTEXT RequestContext,
805807 ccb = RequestContext -> IrpSp -> FileObject -> FsContext2 ;
806808 ASSERT (ccb != NULL );
807809
810+ fcb = ccb -> Fcb ;
811+ ASSERT (fcb != NULL );
812+
808813 infoClass = RequestContext -> IrpSp -> Parameters .SetFile .FileInformationClass ;
809814 DOKAN_LOG_FINE_IRP (RequestContext , "FileObject=%p infoClass=%s" ,
810815 RequestContext -> IrpSp -> FileObject ,
@@ -816,30 +821,17 @@ VOID DokanCompleteSetInformation(__in PREQUEST_CONTEXT RequestContext,
816821 return ;
817822 }
818823
819- fcb = ccb -> Fcb ;
820- ASSERT (fcb != NULL );
821-
822- switch (RequestContext -> IrpSp -> Parameters .SetFile .FileInformationClass ) {
823- case FileAllocationInformation :
824- DokanNotifyReportChange (RequestContext , fcb , FILE_NOTIFY_CHANGE_SIZE ,
825- FILE_ACTION_MODIFIED );
826- break ;
827- case FileBasicInformation :
828- DokanNotifyReportChange (
829- RequestContext , fcb ,
830- FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_LAST_WRITE |
831- FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION ,
832- FILE_ACTION_MODIFIED );
833- break ;
824+ // Process changes
825+ switch (infoClass ) {
834826 case FileDispositionInformation :
835827 case FileDispositionInformationEx : {
828+ // Note that we do not acquire the resource for paging file
829+ // operations in order to avoid deadlock with Mm
830+ fcbLocked = !(RequestContext -> Irp -> Flags & IRP_PAGING_IO );
831+ if (fcbLocked ) {
832+ DokanFCBLockRW (fcb );
833+ }
836834 if (EventInfo -> Operation .Delete .DeleteOnClose ) {
837- // Note that we do not acquire the resource for paging file
838- // operations in order to avoid deadlock with Mm
839- BOOLEAN fcbLocked = !(RequestContext -> Irp -> Flags & IRP_PAGING_IO );
840- if (fcbLocked ) {
841- DokanFCBLockRW (fcb );
842- }
843835 if (!MmFlushImageSection (& fcb -> SectionObjectPointers , MmFlushForDelete )) {
844836 DOKAN_LOG_FINE_IRP (RequestContext , "Cannot delete user mapped image" );
845837 RequestContext -> Irp -> IoStatus .Status = STATUS_CANNOT_DELETE ;
@@ -849,53 +841,76 @@ VOID DokanCompleteSetInformation(__in PREQUEST_CONTEXT RequestContext,
849841 DOKAN_LOG_FINE_IRP (RequestContext , "FileObject->DeletePending = TRUE" );
850842 RequestContext -> IrpSp -> FileObject -> DeletePending = TRUE;
851843 }
852- if (fcbLocked ) {
853- DokanFCBUnlock (fcb );
854- }
844+
855845 } else {
856846 DokanCCBFlagsClearBit (ccb , DOKAN_DELETE_ON_CLOSE );
857847 DokanFCBFlagsClearBit (fcb , DOKAN_DELETE_ON_CLOSE );
858848 DOKAN_LOG_FINE_IRP (RequestContext , "FileObject->DeletePending = FALSE" );
859849 RequestContext -> IrpSp -> FileObject -> DeletePending = FALSE;
860850 }
861- if (RequestContext -> IrpSp -> FileObject -> DeletePending ) {
862- if (DokanFCBFlagsIsSet (fcb , DOKAN_FILE_DIRECTORY )) {
863- DokanNotifyReportChange (RequestContext , fcb ,
864- FILE_NOTIFY_CHANGE_DIR_NAME ,
865- FILE_ACTION_REMOVED );
866- } else {
867- DokanNotifyReportChange (RequestContext , fcb ,
868- FILE_NOTIFY_CHANGE_FILE_NAME ,
869- FILE_ACTION_REMOVED );
870- }
871- }
872- } break ;
873- case FileEndOfFileInformation :
874- DokanNotifyReportChange (RequestContext , fcb , FILE_NOTIFY_CHANGE_SIZE ,
875- FILE_ACTION_MODIFIED );
876851 break ;
877- case FileRenameInformationEx :
878- case FileRenameInformation : {
852+ }
853+ case FileRenameInformation :
854+ case FileRenameInformationEx : {
855+ DokanVCBLockRW (RequestContext -> Vcb );
879856 DokanFCBLockRW (fcb );
880857 // Process rename
881- UNICODE_STRING oldFileName =
858+ oldFileName =
882859 DokanWrapUnicodeString (fcb -> FileName .Buffer , fcb -> FileName .Length );
883860 // Copy new file name
884861 PVOID buffer = DokanAllocZero (EventInfo -> BufferLength + sizeof (WCHAR ));
885862 if (buffer == NULL ) {
886863 RequestContext -> Irp -> IoStatus .Status = STATUS_INSUFFICIENT_RESOURCES ;
887864 DokanFCBUnlock (fcb );
865+ DokanVCBUnlock (RequestContext -> Vcb );
888866 return ;
889867 }
890868 RtlCopyMemory (buffer , EventInfo -> Buffer , EventInfo -> BufferLength );
891- DokanVCBLockRW (RequestContext -> Vcb );
892869 DokanRenameFcb (RequestContext , fcb , buffer ,
893870 (USHORT )EventInfo -> BufferLength );
894871 DokanVCBUnlock (RequestContext -> Vcb );
895872 DOKAN_LOG_FINE_IRP (RequestContext , "Fcb=%p renamed \"%wZ\"" , fcb ,
896873 & fcb -> FileName );
897- DokanFCBUnlock (fcb );
898- // Notify rename
874+ break ;
875+ }
876+ default :
877+ DokanFCBLockRO (fcb );
878+ break ;
879+ }
880+
881+ // Notify changes
882+ switch (infoClass ) {
883+ case FileAllocationInformation :
884+ DokanNotifyReportChange (RequestContext , fcb , FILE_NOTIFY_CHANGE_SIZE ,
885+ FILE_ACTION_MODIFIED );
886+ break ;
887+ case FileBasicInformation :
888+ DokanNotifyReportChange (
889+ RequestContext , fcb ,
890+ FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_LAST_WRITE |
891+ FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION ,
892+ FILE_ACTION_MODIFIED );
893+ break ;
894+ case FileDispositionInformation :
895+ case FileDispositionInformationEx :
896+ if (RequestContext -> IrpSp -> FileObject -> DeletePending ) {
897+ if (DokanFCBFlagsIsSet (fcb , DOKAN_FILE_DIRECTORY )) {
898+ DokanNotifyReportChange (RequestContext , fcb ,
899+ FILE_NOTIFY_CHANGE_DIR_NAME ,
900+ FILE_ACTION_REMOVED );
901+ } else {
902+ DokanNotifyReportChange (RequestContext , fcb ,
903+ FILE_NOTIFY_CHANGE_FILE_NAME ,
904+ FILE_ACTION_REMOVED );
905+ }
906+ }
907+ break ;
908+ case FileEndOfFileInformation :
909+ DokanNotifyReportChange (RequestContext , fcb , FILE_NOTIFY_CHANGE_SIZE ,
910+ FILE_ACTION_MODIFIED );
911+ break ;
912+ case FileRenameInformation :
913+ case FileRenameInformationEx : {
899914 if (IsInSameDirectory (& oldFileName , & fcb -> FileName )) {
900915 DokanNotifyReportChange0 (RequestContext , fcb , & oldFileName ,
901916 DokanFCBFlagsIsSet (fcb , DOKAN_FILE_DIRECTORY )
@@ -927,4 +942,7 @@ VOID DokanCompleteSetInformation(__in PREQUEST_CONTEXT RequestContext,
927942 FILE_ACTION_MODIFIED );
928943 break ;
929944 }
945+ if (fcbLocked ) {
946+ DokanFCBUnlock (fcb );
947+ }
930948}
0 commit comments