[FASTFAT]
authorThomas Faber <thomas.faber@reactos.org>
Thu, 15 Sep 2016 13:12:02 +0000 (13:12 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Thu, 15 Sep 2016 13:12:02 +0000 (13:12 +0000)
- 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

index 40aa051..c664af1 100644 (file)
@@ -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,