Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f03d51a

Browse files
committedJan 28, 2022
Kernel - Lock Fcb during setFileInfo notify report change
1 parent eda8609 commit f03d51a

File tree

1 file changed

+63
-45
lines changed

1 file changed

+63
-45
lines changed
 

‎sys/fileinfo.c

+63-45
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)
Please sign in to comment.