[NTOS:IO] Implement IopAcquireFileObjectLock and use it to fix IopLockFileObject

This commit is contained in:
Thomas Faber 2018-10-02 09:55:07 +02:00 committed by Pierre Schweitzer
parent c6142174af
commit 8fbc488050
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
4 changed files with 167 additions and 25 deletions

View file

@ -8,16 +8,26 @@
static
__inline
VOID
IopLockFileObject(IN PFILE_OBJECT FileObject)
NTSTATUS
IopLockFileObject(
_In_ PFILE_OBJECT FileObject,
_In_ KPROCESSOR_MODE WaitMode)
{
BOOLEAN LockFailed;
/* Lock the FO and check for contention */
InterlockedIncrement((PLONG)&FileObject->Waiters);
while (InterlockedCompareExchange((PLONG)&FileObject->Busy, TRUE, FALSE) != FALSE)
if (InterlockedExchange((PLONG)&FileObject->Busy, TRUE) == FALSE)
{
/* FIXME - pause for a little while? */
ObReferenceObject(FileObject);
return STATUS_SUCCESS;
}
else
{
return IopAcquireFileObjectLock(FileObject,
WaitMode,
BooleanFlagOn(FileObject->Flags, FO_ALERTABLE_IO),
&LockFailed);
}
InterlockedDecrement((PLONG)&FileObject->Waiters);
}
static
@ -26,8 +36,12 @@ VOID
IopUnlockFileObject(IN PFILE_OBJECT FileObject)
{
/* Unlock the FO and wake any waiters up */
InterlockedExchange((PLONG)&FileObject->Busy, FALSE);
if (FileObject->Waiters) KeSetEvent(&FileObject->Lock, 0, FALSE);
NT_VERIFY(InterlockedExchange((PLONG)&FileObject->Busy, FALSE) == TRUE);
if (FileObject->Waiters)
{
KeSetEvent(&FileObject->Lock, IO_NO_INCREMENT, FALSE);
}
ObDereferenceObject(FileObject);
}
FORCEINLINE