[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
This commit is contained in:
Thomas Faber 2016-09-15 13:12:02 +00:00
parent a35a286182
commit f2599dd576

View 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,