reactos/ntoskrnl/fs
diff -u -r1.16 -r1.17
--- filelock.c 23 Dec 2004 12:30:48 -0000 1.16
+++ filelock.c 30 Dec 2004 02:30:40 -0000 1.17
@@ -1,4 +1,4 @@
-/* $Id: filelock.c,v 1.16 2004/12/23 12:30:48 ekohl Exp $
+/* $Id: filelock.c,v 1.17 2004/12/30 02:30:40 gdalsnes Exp $
*
* reactos/ntoskrnl/fs/filelock.c
*
@@ -13,18 +13,54 @@
I'm not using resource syncronization here, since FsRtlFastCheckLockForRead/Write
are allowed to be called at DISPATCH_LEVEL. Must therefore use nonpaged memory for
the lists.
+UPDATE: I'm not sure about this! -Gunnar
*/
-#define LOCK_START_OFF(Lock) ((Lock).StartingByte.QuadPart)
-#define LOCK_END_OFF(Lock) (((Lock).StartingByte.QuadPart) + ((Lock).Length.QuadPart) - 1)
-#define REQUEST_START_OFF (FileOffset->QuadPart)
-#define REQUEST_END_OFF ((FileOffset->QuadPart) + (Length->QuadPart) - 1)
-
FAST_MUTEX LockTocMutex;
NPAGED_LOOKASIDE_LIST GrantedLookaside;
NPAGED_LOOKASIDE_LIST LockTocLookaside;
PAGED_LOOKASIDE_LIST LockLookaside;
+
+
+inline BOOLEAN
+IsOverlappingLock(
+ PFILE_LOCK_INFO Lock,
+ PLARGE_INTEGER StartOffset,
+ PLARGE_INTEGER EndOffset
+ )
+{
+ if ((ULONGLONG)StartOffset->QuadPart > (ULONGLONG)Lock->EndingByte.QuadPart)
+ {
+ return FALSE;
+ }
+
+ if ((ULONGLONG)EndOffset->QuadPart < (ULONGLONG)Lock->StartingByte.QuadPart)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+inline BOOLEAN
+IsSurroundingLock(
+ PFILE_LOCK_INFO Lock,
+ PLARGE_INTEGER StartOffset,
+ PLARGE_INTEGER EndOffset
+ )
+{
+ if ((ULONGLONG)StartOffset->QuadPart >= (ULONGLONG)Lock->StartingByte.QuadPart &&
+ (ULONGLONG)EndOffset->QuadPart <= (ULONGLONG)Lock->EndingByte.QuadPart)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
/**********************************************************************
* NAME PRIVATE
* FsRtlpInitFileLockingImplementation
@@ -62,6 +98,7 @@
);
ExInitializeFastMutex(&LockTocMutex);
+
}
/**********************************************************************
@@ -78,28 +115,22 @@
{
KIRQL oldIrql;
PKSPIN_LOCK SpinLock;
- PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine;
//don't need this since we have our own sync. protecting irp cancellation
IoReleaseCancelSpinLock(Irp->CancelIrql);
- SpinLock = &((PFILE_LOCK_TOC)Irp->Tail.Overlay.DriverContext[1])->SpinLock;
+ SpinLock = Irp->Tail.Overlay.DriverContext[3];
KeAcquireSpinLock(SpinLock, &oldIrql);
+
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+
KeReleaseSpinLock(SpinLock, oldIrql);
Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
- CompleteLockIrpRoutine = ((PFILE_LOCK)Irp->Tail.Overlay.DriverContext[0])->CompleteLockIrpRoutine;
- if (CompleteLockIrpRoutine)
- {
- CompleteLockIrpRoutine(Irp->Tail.Overlay.DriverContext[2], Irp);
- }
- else
- {
- IofCompleteRequest(Irp, IO_NO_INCREMENT);
- }
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
@@ -107,6 +138,9 @@
* NAME PRIVATE
* FsRtlpCheckLockForReadOrWriteAccess
*
+ * Return:
+ * TRUE: can read/write
+ * FALSE: can't read/write
*/
BOOLEAN
FASTCALL
@@ -124,8 +158,10 @@
PFILE_LOCK_TOC LockToc;
PFILE_LOCK_GRANTED Granted;
PLIST_ENTRY EnumEntry;
-
+ LARGE_INTEGER EndOffset;
+
ASSERT(FileLock);
+
LockToc = FileLock->LockInformation;
if (LockToc == NULL || Length->QuadPart == 0)
@@ -133,15 +169,16 @@
return TRUE;
}
+ EndOffset.QuadPart = FileOffset->QuadPart + Length->QuadPart - 1;
+
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
- EnumEntry = LockToc->GrantedListHead.Flink;
- while ( EnumEntry != &LockToc->GrantedListHead)
+ LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
{
- Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry );
+ Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED, ListEntry);
+
//if overlapping
- if(!(REQUEST_START_OFF > LOCK_END_OFF(Granted->Lock) ||
- REQUEST_END_OFF < LOCK_START_OFF(Granted->Lock)))
+ if(IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset))
{
//No read conflict if (shared lock) OR (exclusive + our lock)
//No write conflict if exclusive lock AND our lock
@@ -152,30 +189,26 @@
Granted->Lock.Key == Key ) )
{
//AND if lock surround request region, stop searching and grant
- if (REQUEST_START_OFF >= LOCK_START_OFF(Granted->Lock) &&
- REQUEST_END_OFF <= LOCK_END_OFF(Granted->Lock))
+ if (IsSurroundingLock(&Granted->Lock, FileOffset, &EndOffset) )
{
- EnumEntry = &LockToc->GrantedListHead;//indicate no conflict
- break;
+ KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+ return TRUE;
}
+
//else continue searching for conflicts
+ continue;
}
- else //conflict
- {
- break;
- }
- }
- EnumEntry = EnumEntry->Flink;
- }
- KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+ //found conflict
+ KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+ return FALSE;
+ }
- if (EnumEntry == &LockToc->GrantedListHead)
- { //no conflict
- return TRUE;
}
- return FALSE;
+ //no conflict
+ KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+ return TRUE;
}
@@ -206,7 +239,7 @@
Stack->Parameters.Read.Key,
Stack->FileObject,
IoGetRequestorProcess(Irp),
- TRUE//Read?
+ TRUE /* Read */
);
}
@@ -238,7 +271,7 @@
Stack->Parameters.Write.Key,
Stack->FileObject,
IoGetRequestorProcess(Irp),
- FALSE//Read?
+ FALSE /* Read */
);
}
@@ -269,7 +302,7 @@
Key,
FileObject,
Process,
- TRUE//Read?
+ TRUE /* Read */
);
}
@@ -297,7 +330,7 @@
Key,
FileObject,
Process,
- FALSE//Read?
+ FALSE /* Read */
);
}
@@ -314,8 +347,8 @@
IN PFILE_LOCK FileLock,
IN PFILE_OBJECT FileObject,
IN PEPROCESS Process,
- IN DWORD Key, /* FIXME: guess */
- IN BOOLEAN UseKey, /* FIXME: guess */
+ IN DWORD Key,
+ IN BOOLEAN UseKey,
IN PVOID Context OPTIONAL
)
{
@@ -325,7 +358,8 @@
PFILE_LOCK_GRANTED Granted;
BOOLEAN Unlock = FALSE;
//must make local copy since FILE_LOCK struct is allowed to be paged
- PUNLOCK_ROUTINE GotUnlockRoutine;
+ BOOLEAN GotUnlockRoutine;
+ LIST_ENTRY UnlockedListHead;
ASSERT(FileLock);
LockToc = FileLock->LockInformation;
@@ -335,15 +369,13 @@
return STATUS_RANGE_NOT_LOCKED;
}
- GotUnlockRoutine = FileLock->UnlockRoutine;
+ InitializeListHead(&UnlockedListHead);
+ GotUnlockRoutine = FileLock->UnlockRoutine != NULL;
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
-
- EnumEntry = LockToc->GrantedListHead.Flink;
- while (EnumEntry != &LockToc->GrantedListHead )
+
+ LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted, FILE_LOCK_GRANTED, ListEntry)
{
- Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry);
- EnumEntry = EnumEntry->Flink;
-
+
if (Granted->Lock.Process == Process &&
Granted->Lock.FileObject == FileObject &&
(!UseKey || (UseKey && Granted->Lock.Key == Key)) )
@@ -357,7 +389,7 @@
Put on unlocked list and call unlock routine for them afterwards.
This way we don't have to restart enum after each call
*/
- InsertHeadList(&LockToc->UnlockedListHead,&Granted->ListEntry);
+ InsertHeadList(&UnlockedListHead,&Granted->ListEntry);
}
else
{
@@ -366,21 +398,23 @@
}
}
+ KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+
if (Unlock)
{
//call unlock routine for each unlocked lock (if any)
- while (!IsListEmpty(&LockToc->UnlockedListHead))
+ while (!IsListEmpty(&UnlockedListHead))
{
- EnumEntry = RemoveTailList(&LockToc->UnlockedListHead);
+ EnumEntry = RemoveTailList(&UnlockedListHead);
Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry);
- KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
- FileLock->UnlockRoutine(Context,&Granted->Lock);
+
+ FileLock->UnlockRoutine(Granted->UnlockContext, &Granted->Lock);
ExFreeToNPagedLookasideList(&GrantedLookaside,Granted);
- KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
}
//NOTE: holding spinlock while calling this
- FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql);
+ KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
+ FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql, Context);
if (IsListEmpty(&LockToc->GrantedListHead))
{
@@ -391,10 +425,10 @@
{
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
}
+
return STATUS_SUCCESS;
}
- KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
return STATUS_RANGE_NOT_LOCKED;
}
@@ -416,9 +450,9 @@
return FsRtlpFastUnlockAllByKey( FileLock,
FileObject,
Process,
- 0, /* Key */
+ 0, /* Key is ignored */
FALSE, /* Do NOT use Key */
- Context
+ Context
);
}
@@ -443,7 +477,7 @@
Process,
Key,
TRUE, /* Use Key */
- Context
+ Context
);
}
@@ -455,7 +489,7 @@
* NOTE
* Spinlock held at entry !!
*/
-NTSTATUS
+BOOLEAN
FASTCALL
FsRtlpAddLock(
IN PFILE_LOCK_TOC LockToc,
@@ -464,58 +498,60 @@
IN PLARGE_INTEGER Length,
IN PEPROCESS Process,
IN ULONG Key,
- IN BOOLEAN ExclusiveLock
+ IN BOOLEAN ExclusiveLock,
+ IN PVOID Context
)
{
PLIST_ENTRY EnumEntry;
PFILE_LOCK_GRANTED Granted;
+ LARGE_INTEGER EndOffset;
+
+ EndOffset.QuadPart = FileOffset->QuadPart + Length->QuadPart - 1;
- EnumEntry = LockToc->GrantedListHead.Flink;
- while (EnumEntry != &LockToc->GrantedListHead)
+ //loop and try to find conflicking locks
+ LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
{
Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry);
- //if overlapping
- if(!(REQUEST_START_OFF > LOCK_END_OFF(Granted->Lock) ||
- REQUEST_END_OFF < LOCK_START_OFF(Granted->Lock)))
+
+ if (IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset))
{
- //never conflict if shared lock and we want to add a shared lock
+ //we found a locks that overlap with the new lock
+
+ //if both locks are shared, we might have a fast path outa here...
if (!Granted->Lock.ExclusiveLock && !ExclusiveLock)
{
- //AND if lock surround region, stop searching and insert lock
- if (REQUEST_START_OFF >= LOCK_START_OFF(Granted->Lock) &&
- REQUEST_END_OFF <= LOCK_END_OFF(Granted->Lock))
+ //if existing lock surround new lock, we know that no other exclusive lock
+ //may overlap with our new lock;-D
+ if (IsSurroundingLock(&Granted->Lock, FileOffset, &EndOffset))
{
- EnumEntry = &LockToc->GrantedListHead;
break;
}
+
//else keep locking for conflicts
+ continue;
}
- else
- {//conflict if we want share access to excl. lock OR exlc. access to shared lock
- break;//FAIL
- }
+
+ //we found a conflict:
+ //we want shared access to an excl. lock OR exlc. access to a shared lock
+ return FALSE;
}
- EnumEntry = EnumEntry->Flink;
}
- if (EnumEntry == &LockToc->GrantedListHead)
- {//no conflict
- Granted = ExAllocateFromNPagedLookasideList(&GrantedLookaside);
-
- Granted->Lock.StartingByte = *FileOffset;
- Granted->Lock.Length = *Length;
- Granted->Lock.ExclusiveLock = ExclusiveLock;
- Granted->Lock.Key = Key;
- Granted->Lock.FileObject = FileObject;
- Granted->Lock.Process = Process;
- Granted->Lock.EndingByte.QuadPart = REQUEST_END_OFF;
+ Granted = ExAllocateFromNPagedLookasideList(&GrantedLookaside);
- InsertHeadList(&LockToc->GrantedListHead,&Granted->ListEntry);
- return TRUE;
- }
-
- return FALSE;
+ //starting offset
+ Granted->Lock.StartingByte = *FileOffset;
+ Granted->Lock.Length = *Length;
+ Granted->Lock.ExclusiveLock = ExclusiveLock;
+ Granted->Lock.Key = Key;
+ Granted->Lock.FileObject = FileObject;
+ Granted->Lock.Process = Process;
+ //ending offset
+ Granted->Lock.EndingByte = EndOffset;
+ Granted->UnlockContext = Context;
+ InsertHeadList(&LockToc->GrantedListHead,&Granted->ListEntry);
+ return TRUE;
}
@@ -532,19 +568,20 @@
FsRtlpCompletePendingLocks(
IN PFILE_LOCK FileLock,
IN PFILE_LOCK_TOC LockToc,
- IN OUT PKIRQL oldirql
+ IN OUT PKIRQL oldirql,
+ IN PVOID Context
)
{
//walk pending list, FIFO order, try 2 complete locks
PLIST_ENTRY EnumEntry;
PIRP Irp;
PIO_STACK_LOCATION Stack;
-
- EnumEntry = LockToc->PendingListHead.Blink;
- while (EnumEntry != &LockToc->PendingListHead)
+ LIST_ENTRY CompletedListHead;
+
+ InitializeListHead(&CompletedListHead);
+
+ LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->PendingListHead, Irp, IRP, Tail.Overlay.ListEntry)
{
- Irp = CONTAINING_RECORD(EnumEntry,IRP, Tail.Overlay.ListEntry);
-
Stack = IoGetCurrentIrpStackLocation(Irp);
if (FsRtlpAddLock(LockToc,
Stack->FileObject,
@@ -552,55 +589,65 @@
Stack->Parameters.LockControl.Length,
IoGetRequestorProcess(Irp),
Stack->Parameters.LockControl.Key,
- Stack->Flags & SL_EXCLUSIVE_LOCK
+ Stack->Flags & SL_EXCLUSIVE_LOCK,
+ Irp->Tail.Overlay.DriverContext[2] //Context
) )
{
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
if (!IoSetCancelRoutine(Irp, NULL))
{
- /*
- Cancel routine WILL be called after we release the spinlock. It will try to remove
- the irp from the list and cancel/complete this irp. Since we allready removed it,
- make its ListEntry point to itself.
- */
+ //irp is canceled and cancelroutine will run when we release the lock
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
+ continue;
}
- else
- {
- /*
- Cancel routine will NOT be called, canceled or not.
- Put on completed list and complete them all afterwards.
- This way we don't have to restart enum after each completion.
- */
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- InsertHeadList(&LockToc->CompletedListHead,&Irp->Tail.Overlay.ListEntry);
- }
+ /*
+ Put on completed list and complete them all afterwards.
+ This way we don't have to restart enum after each completion.
+ */
+ InsertHeadList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry);
}
- EnumEntry = EnumEntry->Blink;
}
+ KeReleaseSpinLock(&LockToc->SpinLock, *oldirql);
+
//complete irp's (if any)
- while (!IsListEmpty(&LockToc->CompletedListHead))
+ while (!IsListEmpty(&CompletedListHead))
{
- EnumEntry = RemoveTailList(&LockToc->CompletedListHead);
- KeReleaseSpinLock(&LockToc->SpinLock, *oldirql);//fires cancel routine
+ EnumEntry = RemoveTailList(&CompletedListHead);
+
Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
if (FileLock->CompleteLockIrpRoutine)
{
- FileLock->CompleteLockIrpRoutine(Irp->Tail.Overlay.DriverContext[2], Irp);
+ if (FileLock->CompleteLockIrpRoutine(Context, Irp)!=STATUS_SUCCESS)
+ {
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+
+ //revert
+ FsRtlpUnlockSingle ( FileLock,
+ Stack->FileObject,
+ &Stack->Parameters.LockControl.ByteOffset,
+ Stack->Parameters.LockControl.Length,
+ IoGetRequestorProcess(Irp),
+ Stack->Parameters.LockControl.Key,
+ NULL, /* unused context */
+ FALSE /* don't call unlock copletion rout.*/
+ );
+ }
}
else
{
- IofCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
- KeAcquireSpinLock(&LockToc->SpinLock, oldirql);
}
+ KeAcquireSpinLock(&LockToc->SpinLock, oldirql);
}
@@ -620,7 +667,6 @@
IN PEPROCESS Process,
IN ULONG Key,
IN PVOID Context OPTIONAL,
- IN BOOLEAN AlreadySynchronized,
IN BOOLEAN CallUnlockRoutine
)
{
@@ -632,18 +678,16 @@
ASSERT(FileLock);
LockToc = FileLock->LockInformation;
- if (LockToc == NULL || Length->QuadPart == 0)
+ if (LockToc == NULL)
{
return STATUS_RANGE_NOT_LOCKED;
}
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql );
- EnumEntry = LockToc->GrantedListHead.Flink;
- while (EnumEntry != &LockToc->GrantedListHead)
+ LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted,FILE_LOCK_GRANTED,ListEntry)
{
- Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED,ListEntry);
-
+
//must be exact match
if (FileOffset->QuadPart == Granted->Lock.StartingByte.QuadPart &&
Length->QuadPart == Granted->Lock.Length.QuadPart &&
@@ -652,12 +696,13 @@
Granted->Lock.Key == Key)
{
RemoveEntryList(&Granted->ListEntry);
- FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql);
+ FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql, Context);
if (IsListEmpty(&LockToc->GrantedListHead))
{
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
- FsRtlAreThereCurrentFileLocks(FileLock) = FALSE;
+
+ FsRtlAreThereCurrentFileLocks(FileLock) = FALSE; //paged data
}
else
{
@@ -666,14 +711,13 @@
if (FileLock->UnlockRoutine && CallUnlockRoutine)
{
- FileLock->UnlockRoutine(Context,&Granted->Lock);
+ FileLock->UnlockRoutine(Granted->UnlockContext, &Granted->Lock);
}
- ExFreeToNPagedLookasideList(&GrantedLookaside,Granted);
+ ExFreeToNPagedLookasideList(&GrantedLookaside, Granted);
return STATUS_SUCCESS;
}
- EnumEntry = EnumEntry->Flink;
}
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
@@ -710,8 +754,7 @@
Process,
Key,
Context,
- AlreadySynchronized,
- TRUE//CallUnlockRoutine
+ TRUE /* call unlock copletion routine */
);
}
@@ -747,11 +790,10 @@
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
- EnumEntry = LockToc->GrantedListHead.Blink;
- while ( EnumEntry != &LockToc->GrantedListHead)
+ LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
{
- Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry );
-
+ Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry);
+
DPRINT1("%s, start: %i, len: %i, end: %i, key: %i, proc: 0x%X, fob: 0x%X\n",
Granted->Lock.ExclusiveLock ? "EXCL" : "SHRD",
Granted->Lock.StartingByte.QuadPart,
@@ -762,16 +804,13 @@
Granted->Lock.FileObject
);
- EnumEntry = EnumEntry->Blink;
}
DPRINT1("Dumping pending file locks, FIFO order\n");
- EnumEntry = LockToc->PendingListHead.Blink;
- while ( EnumEntry != &LockToc->PendingListHead)
+ LIST_FOR_EACH(EnumEntry, &LockToc->PendingListHead)
{
- Irp = CONTAINING_RECORD(EnumEntry, IRP , Tail.Overlay.ListEntry );
-
+ Irp = CONTAINING_RECORD(EnumEntry, IRP , Tail.Overlay.ListEntry);
Stack = IoGetCurrentIrpStackLocation(Irp);
DPRINT1("%s, start: %i, len: %i, end: %i, key: %i, proc: 0x%X, fob: 0x%X\n",
@@ -784,7 +823,6 @@
Stack->FileObject
);
- EnumEntry = EnumEntry->Blink;
}
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
@@ -939,7 +977,7 @@
IN BOOLEAN ExclusiveLock,
OUT PIO_STATUS_BLOCK IoStatus,
IN PIRP Irp OPTIONAL,
- IN PVOID Context,
+ IN PVOID Context OPTIONAL,
IN BOOLEAN AlreadySynchronized
)
{
@@ -958,8 +996,6 @@
KeInitializeSpinLock(&LockToc->SpinLock);
InitializeListHead(&LockToc->GrantedListHead);
InitializeListHead(&LockToc->PendingListHead);
- InitializeListHead(&LockToc->CompletedListHead);
- InitializeListHead(&LockToc->UnlockedListHead);
}
ExReleaseFastMutex(&LockTocMutex);
}
@@ -974,43 +1010,36 @@
Length,
Process,
Key,
- ExclusiveLock
+ ExclusiveLock,
+ Context
) )
{
IoStatus->Status = STATUS_SUCCESS;
}
else if (Irp && !FailImmediately)
- { //failed + irp + no fail = mk. pending
- //for our cancel routine
- Irp->Tail.Overlay.DriverContext[0] = (PVOID)FileLock;
- Irp->Tail.Overlay.DriverContext[1] = (PVOID)LockToc;
- Irp->Tail.Overlay.DriverContext[2] = Context;
+ {
+ //failed + irp + no fail = make. pending
+ Irp->Tail.Overlay.DriverContext[3] = &LockToc->SpinLock;
+ Irp->Tail.Overlay.DriverContext[2] = Context;
+
IoSetCancelRoutine(Irp, FsRtlpFileLockCancelRoutine);
-
- if (Irp->Cancel)
- {
- //irp canceled even before we got to queue it
- if (IoSetCancelRoutine(Irp, NULL))
- { //Cancel routine will NOT be called: cancel it here
- IoStatus->Status = STATUS_CANCELLED;
- }
- else
- { //Cancel routine WILL be called. When we release the lock it will complete the irp
- //Return pending since we are not completing the irp here
- Irp->IoStatus.Status = IoStatus->Status = STATUS_PENDING;
- Irp->IoStatus.Information = 0;
- InitializeListHead(&Irp->Tail.Overlay.ListEntry);
- }
+ if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
+ {
+ //irp was canceled
+ KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return TRUE;
}
- else
- { //not cancelled: queue irp
- IoMarkIrpPending(Irp);
+
+ IoMarkIrpPending(Irp);
Irp->IoStatus.Status = IoStatus->Status = STATUS_PENDING;
Irp->IoStatus.Information = 0;
- InsertHeadList(&LockToc->PendingListHead,&Irp->Tail.Overlay.ListEntry);
- }
+ InsertHeadList(&LockToc->PendingListHead,&Irp->Tail.Overlay.ListEntry);
}
else
@@ -1034,11 +1063,9 @@
{
Irp->IoStatus.Status = IoStatus->Status;
Irp->IoStatus.Information = 0;
-
if (FileLock->CompleteLockIrpRoutine)
- { //complete irp routine
-
- if (!NT_SUCCESS(FileLock->CompleteLockIrpRoutine(Context,Irp)))
+ {
+ if (FileLock->CompleteLockIrpRoutine(Context,Irp)!=STATUS_SUCCESS)
{
//CompleteLockIrpRoutine complain: revert changes
FsRtlpUnlockSingle( FileLock,
@@ -1047,15 +1074,14 @@
Length,
Process,
Key,
- Context,
- AlreadySynchronized,
- FALSE//CallUnlockRoutine
+ NULL, /* context */
+ FALSE /* don't call unlock copletion routine */
);
}
}
else
- {//std irp completion
- IofCompleteRequest(Irp, IO_NO_INCREMENT);
+ {
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
}
}
@@ -1115,7 +1141,7 @@
Stack->Parameters.LockControl.Length,
IoGetRequestorProcess(Irp),
Stack->Parameters.LockControl.Key,
- Context,
+ Context,
FALSE);
break;
@@ -1123,7 +1149,7 @@
Status = FsRtlFastUnlockAll( FileLock,
Stack->FileObject,
IoGetRequestorProcess(Irp),
- Context);
+ Context );
break;
case IRP_MN_UNLOCK_ALL_BY_KEY:
@@ -1131,26 +1157,21 @@
Stack->FileObject,
IoGetRequestorProcess(Irp),
Stack->Parameters.LockControl.Key,
- Context);
+ Context );
break;
default:
Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST;
- IofCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
- Irp->IoStatus.Status = Status;
- if (FileLock->CompleteLockIrpRoutine )
- {
- FileLock->CompleteLockIrpRoutine(Context,Irp);
- }
- else
- {
- IofCompleteRequest(Irp,IO_NO_INCREMENT);
- }
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp,IO_NO_INCREMENT);
return Status;
}
@@ -1202,28 +1223,17 @@
{
//The cancel routine will be called. When we release the lock it will complete the irp.
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
+ continue;
}
- else
- {
- /*
- Cancel routine will NOT be called, even though the irp might have been canceled.
- Don't care since we'l complete it faster than the cancel routine would have.
- */
- KeReleaseSpinLock(&LockToc->SpinLock, oldirql);//fires cancel routine
- Irp->IoStatus.Status = STATUS_RANGE_NOT_LOCKED;
-
- if (FileLock->CompleteLockIrpRoutine)
- {
- FileLock->CompleteLockIrpRoutine(Irp->Tail.Overlay.DriverContext[2], Irp);
- }
- else
- {
- IofCompleteRequest(Irp, IO_NO_INCREMENT);
- }
+ KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+
+ Irp->IoStatus.Status = STATUS_RANGE_NOT_LOCKED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
- KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
- }
}
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
@@ -1311,4 +1321,5 @@
UNIMPLEMENTED;
}
+
/* EOF */