From f2599dd576c0cbcb387ee41082c95daf4747249e Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Thu, 15 Sep 2016 13:12:02 +0000 Subject: [PATCH] [FASTFAT] - Acquire DirResource before MainResource in DoQuery to keep locking order consistent and avoid deadlocks. Patch by Volodymyr Shcherbyna with small modification by me. CORE-11959 CORE-11652 svn path=/trunk/; revision=72681 --- reactos/drivers/filesystems/fastfat/dir.c | 28 ++++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/reactos/drivers/filesystems/fastfat/dir.c b/reactos/drivers/filesystems/fastfat/dir.c index 40aa0512eff..c664af13a66 100644 --- a/reactos/drivers/filesystems/fastfat/dir.c +++ b/reactos/drivers/filesystems/fastfat/dir.c @@ -158,7 +158,7 @@ VfatGetFileDirectoryInformation( pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster); } - + pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f; } else @@ -421,9 +421,20 @@ DoQuery( #endif Buffer = VfatGetUserBuffer(IrpContext->Irp, FALSE); + if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, + BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) + { + Status = VfatLockUserBuffer(IrpContext->Irp, BufferLength, IoWriteAccess); + if (NT_SUCCESS(Status)) + Status = STATUS_PENDING; + + return Status; + } + if (!ExAcquireResourceSharedLite(&pFcb->MainResource, BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) { + ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); Status = VfatLockUserBuffer(IrpContext->Irp, BufferLength, IoWriteAccess); if (NT_SUCCESS(Status)) Status = STATUS_PENDING; @@ -447,7 +458,7 @@ DoQuery( * -> The pattern length is not null * -> The pattern buffer is not null * Otherwise, we'll fall later and allocate a match all (*) pattern - */ + */ if (pSearchPattern && pSearchPattern->Length != 0 && pSearchPattern->Buffer != NULL) { @@ -461,6 +472,7 @@ DoQuery( if (!pCcb->SearchPattern.Buffer) { ExReleaseResourceLite(&pFcb->MainResource); + ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&pCcb->SearchPattern, pSearchPattern); @@ -477,6 +489,7 @@ DoQuery( if (!pCcb->SearchPattern.Buffer) { ExReleaseResourceLite(&pFcb->MainResource); + ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); return STATUS_INSUFFICIENT_RESOURCES; } pCcb->SearchPattern.Buffer[0] = L'*'; @@ -504,13 +517,6 @@ DoQuery( DirContext.ShortNameU.Buffer = ShortNameBuffer; DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer); - if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, - BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) - { - ExReleaseResourceLite(&pFcb->MainResource); - return STATUS_PENDING; - } - while ((Status == STATUS_SUCCESS) && (BufferLength > 0)) { Status = FindFile(IrpContext->DeviceExt, @@ -586,8 +592,8 @@ DoQuery( IrpContext->Irp->IoStatus.Information = Stack->Parameters.QueryDirectory.Length - BufferLength; } - ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); ExReleaseResourceLite(&pFcb->MainResource); + ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); return Status; } @@ -600,7 +606,7 @@ NTSTATUS VfatNotifyChangeDirectory(PVFAT_IRP_CONTEXT IrpContext) Stack = IrpContext->Stack; pVcb = IrpContext->DeviceExt; pFcb = (PVFATFCB) IrpContext->FileObject->FsContext; - + FsRtlNotifyFullChangeDirectory(pVcb->NotifySync, &(pVcb->NotifyList), IrpContext->FileObject->FsContext2,